memcache/request.h
author Tero Marttila <terom@fixme.fi>
Fri, 29 Aug 2008 23:31:17 +0300
changeset 48 1c67f512779b
parent 44 03a7e064f833
child 49 10c7dce1a043
permissions -rw-r--r--
fix doc tpyos, rename some enums, fix printf format len for non-zero terminated strings (hg status), pass args to memcache_cmd_format_header via memcache_req_*, handle zero-length STORE requests, memcache_req is_buf_ours + free, other function name typos (keymemcache_req_key), fix req state behaviour re *_DATA_* for STORE requests and FETCH/END, better memcache_server connpool events/management, modular memcache_test with a working benchmark. This is a long commit message.
#ifndef MEMCACHE_REQ_H
#define MEMCACHE_REQ_H

#include <sys/queue.h>

#include "../memcache.h"
#include "connection.h"

struct memcache_req {
    // the memcache context that we belong to
    struct memcache *mc;

    // the command to execute
    enum memcache_command cmd_type;

    // the reply we have received, or MEMCACHE_REPLY_INVALID
    enum memcache_reply reply_type;

    // our key/obj
    struct memcache_key key;
    struct memcache_obj obj;
    struct memcache_buf buf;

    // flags to indicate if we have valid obj/buf data, and if buf.data was allocated by us or supplied by the user
    char have_obj, have_buf, is_buf_ours;

    // our state
    enum memcache_state state;

    // our user callback argument
    void *cb_arg;

    // the conn 
    struct memcache_connection *conn;
    
    // we are a member of struct memcache_server.req_queue
    TAILQ_ENTRY(memcache_req) reqqueue_node;
};

/*
 * Allocate and return a new req, or NULL if unsuccesfull.
 */
struct memcache_req *memcache_req_alloc (struct memcache *mc, enum memcache_command cmd_type, const struct memcache_key *key, const struct memcache_obj *obj, const struct memcache_buf *buf, void *cb_arg);

/*
 * The request has been queued.
 */
void memcache_req_queued (struct memcache_req *req);

/*
 * The request is being sent.
 */
void memcache_req_send (struct memcache_req *req);

/*
 * The reply has been received, although if the respones also contains data, that will be notified separately.
 *
 * If the response doesn't contain any data, req_done will be called after this is. Otherwise, this will be called
 * first, followed by zero or more calls to req_data, followed by req_reply/RPL_END + req_done.
 *
 * Note that no req data will not be available when this is first called, only once req_data/req_done is called.
 */
void memcache_req_recv (struct memcache_req *req, enum memcache_reply reply_type);

/*
 * Some amount of reply data has been received. This may be called between the req_reply/MEMCACHE_RPL_VALUE and
 * req_reply/MEMCACHE_RPL_END + req_done notifications.
 *
 * Note that this is not always called, it is possible that one might have:
 *      memcache_req_reply(req, MEMCACHE_RPL_VALUE)
 *      memcache_req_reply(req, MEMCACHE_RPL_END)
 *      memcache_req_done(req)
 *
 * This will happen if both the value and the end replies are received in the same chunk.
 *
 * Note also that replies may have zero-length entries, in which case req_data will never be called either.
 */
void memcache_req_data (struct memcache_req *req);

/*
 * The request was sent and is now done, and is not associated with the connection anymore.
 *
 * This will be called before req_reply/req_data, but not before/after req_error.
 *
 * The request will not be accessed anymore after calling this.
 */
void memcache_req_done (struct memcache_req *req);

/*
 * An error occurred, and the request must be abandoned. The request is not active or enqueued anymore.
 *
 * The request will not be accessed anymore after calling this.
 */
void memcache_req_error (struct memcache_req *req);

/*
 * Free an unused req. Should always be called by the user, not via internal means.
 */
void memcache_req_free (struct memcache_req *req);

#endif /* MEMCACHE_REQ_H */