Fix connect bug in memcached_flush_buffers and syntax bug in noreply
authorTrond Norbye <trond.norbye@sun.com>
Fri, 23 Jan 2009 08:52:17 +0000 (09:52 +0100)
committerTrond Norbye <trond.norbye@sun.com>
Fri, 23 Jan 2009 08:52:17 +0000 (09:52 +0100)
When I fixed the bug in memcached_flush_buffers I also improved the test
case for noreply (checking that the items got stored). This revealed
that I had a format bug in the noreply code for the textual protocol causing
protocol error instead of setting the items...

libmemcached/memcached_flush_buffers.c
libmemcached/memcached_storage.c
tests/function.c

index 0a0fffb62892039ac24f70d737f701058071d2bb..f955dbe645c95755fcc534439e0ef88d63a3048e 100644 (file)
@@ -6,8 +6,17 @@ memcached_return memcached_flush_buffers(memcached_st *mem)
   memcached_return ret= MEMCACHED_SUCCESS;
 
   for (int x= 0; x < mem->number_of_hosts; ++x)
-    if (memcached_io_write(&mem->hosts[x], NULL, 0, 1) == -1)
-      ret= MEMCACHED_SOME_ERRORS;
+    if (mem->hosts[x].write_buffer_offset != 0) 
+    {
+      if (mem->hosts[x].fd == -1 &&
+          (ret= memcached_connect(&mem->hosts[x])) != MEMCACHED_SUCCESS)
+      {
+        WATCHPOINT_ERROR(ret);
+        return ret;
+      }
+      if (memcached_io_write(&mem->hosts[x], NULL, 0, 1) == -1)
+        ret= MEMCACHED_SOME_ERRORS;
+    }
 
   return ret;
 }
index 0b8a76857eb2a68b7c99733e34d67a5f1bb062c1..f3c63300f93cd82dd57057eef1969c6370e46c80 100644 (file)
@@ -89,17 +89,21 @@ static inline memcached_return memcached_send(memcached_st *ptr,
 
   if (cas)
     write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
-                           "%s %s%.*s %u %llu %zu %llu\r\n", storage_op_string(verb),
+                           "%s %s%.*s %u %llu %zu %llu%s\r\n", 
+                           storage_op_string(verb),
                            ptr->prefix_key,
                            (int)key_length, key, flags, 
                            (unsigned long long)expiration, value_length, 
-                           (unsigned long long)cas);
+                           (unsigned long long)cas,
+                           (ptr->flags & MEM_NOREPLY) ? " noreply" : "");
   else
     write_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, 
-                           "%s %s%.*s %u %llu %zu\r\n", storage_op_string(verb),
+                           "%s %s%.*s %u %llu %zu%s\r\n", 
+                           storage_op_string(verb),
                            ptr->prefix_key,
                            (int)key_length, key, flags, 
-                           (unsigned long long)expiration, value_length);
+                           (unsigned long long)expiration, value_length,
+                           (ptr->flags & MEM_NOREPLY) ? " noreply" : "");
 
   if (write_length >= MEMCACHED_DEFAULT_COMMAND_SIZE)
   {
@@ -124,25 +128,18 @@ static inline memcached_return memcached_send(memcached_st *ptr,
   else
     to_write= 1;
 
-  if (ptr->flags & MEM_NOREPLY)
-  {
-    if (memcached_io_write(&ptr->hosts[server_key], " noreply\r\n", 
-                           10, to_write) == -1)
-    {
-      rc= MEMCACHED_WRITE_FAILURE;
-      goto error;
-    }
-
-    memcached_server_response_decrement(&ptr->hosts[server_key]);
-    return (to_write == 0) ? MEMCACHED_BUFFERED : MEMCACHED_SUCCESS;
-  }
-
   if ((sent_length= memcached_io_write(&ptr->hosts[server_key], "\r\n", 2, to_write)) == -1)
   {
     rc= MEMCACHED_WRITE_FAILURE;
     goto error;
   }
 
+  if (ptr->flags & MEM_NOREPLY)
+  {
+    memcached_server_response_decrement(&ptr->hosts[server_key]);
+    return (to_write == 0) ? MEMCACHED_BUFFERED : MEMCACHED_SUCCESS;
+  }
+
   if (to_write == 0)
     return MEMCACHED_BUFFERED;
 
index 6ee9f27bc993fb7263d80ef50b1919211b4d040c..42547870216e45e751f9617f7e189e394cd9ba5f 100644 (file)
@@ -3070,6 +3070,22 @@ static test_return noreply_test(memcached_st *memc)
      assert(no_msg == 0);
 
   assert(memcached_flush_buffers(memc) == MEMCACHED_SUCCESS);
+
+  /*
+  ** Now validate that all items was set properly!
+  */
+  for (int x= 0; x < 100; ++x) {
+    char key[10];
+    size_t len= sprintf(key, "%d", x);
+    size_t length;
+    uint32_t flags;
+    char* value= memcached_get(memc, key, strlen(key), 
+                               &length, &flags, &ret);    
+    assert(ret == MEMCACHED_SUCCESS && value != NULL);
+    assert(strncmp(value, key, len) == 0);
+    free(value);
+  }
+
   return TEST_SUCCESS;
 }