C API
Brad Fitzpatrick
brad@danga.com
Fri, 16 Jan 2004 09:27:37 -0800 (PST)
I'm thinking something like this would be better:
/* gets a handle for a group of servers. could set the servers here,
the domain, the time-out restrictions, etc. like the Perl API.
also, perhaps a function pointer to the memory allocator, if not
malloc. */
memcached_client* memcached_client_new(opts...);
/* for add/replace/set/delete: return boolean if "STORED" or "DELETED" */
int memcached_VERB(memcached_client* mc, const char *key, ushort flags,
time_t seconds, const char *data, size_t data_len);
/* gets a single item, using mc's allocator, or nothing. */
char* memcached_get(memcached_client* mc, const char *key);
/* same, with an explicit hash value */
char* memcached_get(memcached_client* mc, uint hv, const char *key);
/* get multi, returns count of items retrieved */
struct mc_iovec {
char *key; /* set by caller */
int hv; /* set by caller. -1 means no explicit hashvalue */
int length; /* set by caller to -1, set to length by get_multi */
char *pointer; /* set by get_multi if length > 0 */
};
int memcached_get_multi(memcached_client* mc, struct mc_iovec *vector,
size_t count);
The "connect" stuff is an internal detail, not part of the public API.
You don't make clients deal with that. They just want to get/set and not
know from where.
But if you're doing cache-sensitive stuff (like MySQL's row cache) you
will need to know things like connect failures, so you'll probably need
another struct for each server, hanging off *memcached_client, which you
can check for errors.
Also, you'll want internal functions which return the non-blocking
socket fds to wait on in your select loop. (memcached should never assume
a server is up or functioning quickly. your select timeout is specified
in *memcached_client.... something like a half second or a second at
most.)
Avva--- anything I'm forgetting?
On Fri, 16 Jan 2004, Brian Aker wrote:
> I posted this last night to my blog and decided to repost it here to get
> a little more feedback (and possibly some suggestions on the API):
>
> Thus far I have something like this:
>
> void connect_memcached();
> void stats_memcached();
> void delete_memcached(const char *key, time_t seconds);
> void add_memcached(const char *key, int flags, time_t seconds, const
> char *data, size_t data_len);
> void replace_memcached(const char *key, int flags, time_t seconds, const
> char *data, size_t data_len);
> void set_memcached(const char *key, int flags, time_t seconds, const
> char *data, size_t data_len);
> void get_memcached(const char *key);
> void close_memcached();
>
>
> I am thinking about defining some sort of client structure that will be
> passed into connect_memcached().
> Store in it:
> socket
> buffer
> some sort of len about the data in the buffer
>
> "buffer" I would like to define.... not sure what. Part of me is tempted
> to define it as default tcp packet size so that I know I am fetching all
> data each read.
>
> Need to add a fetch method where you pass in buffer and I then copy from
> client structure. Dealing with multiple get requests is somewhat of a
> pain I might add.
>
> Same with error messages since they are completely made up of strings
> (do a bunch of strcmp and return integer equivs?).
>
> Memecache's protocol is a half text/half binary protocol. Shame its not
> a complete binary protocol since I could avoid a bit of parsing that
> way. Though its text base it has no parser and its not very wordy (I
> have to say I have become accustom to just pulling out YACC/LEX and
> going to town (though I am becoming fond of PCCTS)).
>
> No authentication currently.
>
> Trying to avoid malloc() calls since they basically suck for
> performance.
>
> Need to think a bit a more on the stats method too...
>
> --
> _______________________________________________________
> Brian "Krow" Aker, brian@tangent.org
> Seattle, Washington
> http://krow.net/
> http://askbrian.org/
> _______________________________________________________
> You can't grep a dead tree.
>
>