libmemcached "protocol error" and "Server sent data for key not in request"

Ted Schundler tschundler at gmail.com
Tue Mar 29 16:38:08 PST 2005


Ah, this is the same issue related Alermo's problems in a different thread.
And I think I have a solution, at least to the delay issue:

in memcached in set_cork(), change it to:
void set_cork() (conn *c, int val) {
   if (c->is_corked == val) return;
   c->is_corked = val;
#ifdef TCP_NOPUSH
   setsockopt(c->sfd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val));
   val!=val;
   setsockopt(c->sfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
#endif
}

so, at very least it's guaranteed that when the cork is released, the
packets go out.  Then there are no delay problems with inconveniently
sized packets. And I don't think it will break compatability with Linux.

Ted


On Thu, 17 Mar 2005 16:40:47 +0000, Richard Cameron
<camster at citeulike.org> wrote:
> 
> Does anyone else see these two errors with libmemcached:
> 
> regress: memcache.c:1096        protocol error: Unknown error: 0
> regress: memcache.c:1031        Server sent data for key not in request.
> 
> I see them on Mac OS X but not on Linux. It's a reasonably slow
> machine, and it's got the disadvantage of not having a working
> TCP_NOPUSH, so what appears to be happening is the data seems to be
> coming back from the server in dribs and drabs.
> 
> It appears that there are some particularly unfortunate lengths of
> dribs which fool libmemcached into thinking it's getting mangled data
> back from the server. While this  is much more likely to happen on OS
> X, I presume that it's theoretically possible that it might happen on
> Linux too.
> 
> I'm using libmemcached version 1.2.3 and here's my patch which seems to
> calm things down:
> 
> Index: memcache.c
> ===================================================================
> --- memcache.c  (revision 2201)
> +++ memcache.c  (working copy)
> @@ -1011,7 +1011,7 @@
>          * If this fails we will scan the whole list. */
>         if (res != NULL && res->entries.tqe_next != NULL) {
>          for (res = res->entries.tqe_next; res != NULL; res =
> res->entries.tqe_next) {
> -         if ((size_t)(rb - (cp - ms->cur)) > res->len) {
> +         if ((size_t)(ms->read_cur - cp) >= res->len) {
>              if (memcmp(cp, res->key, res->len) == 0) {
>                break;
>              }
> @@ -1019,7 +1019,7 @@
>          }
>         } else {
>          for (res = req->query.tqh_first; res != NULL; res =
> res->entries.tqe_next) {
> -         if((size_t)(rb - (cp - ms->cur)) > res->len) {
> +         if ((size_t)(ms->read_cur - cp) >= res->len) {
>              if(memcmp(cp, res->key, res->len) == 0) {
>                break;
>              }
> @@ -1067,8 +1067,8 @@
> 
>     bytes_read = ms->read_cur - cp;
> 
> -  /* Check if we have read all the data the plus a \r\n */
> -  if (bytes_read >= len + 2) {
> +  /* Check if we have read all the data the plus a \r\n (plus partial
> next item or END)*/
> +  if (bytes_read > len + 2) {
>       res->_flags |= MCM_RES_FOUND;
>       if (res->size == 0) {
>         res->val = ctxt->mcMallocAtomic(res->bytes);
> 
>


More information about the memcached mailing list