Add a request id for each request that hits the wire.
[m6w6/libmemcached] / libmemcached / version.cc
index b889bf4f21667804dffed75f120e80cd2dc8e7b1..9f41c97ae6ac10e7224cb576d81027dc21615fd7 100644 (file)
@@ -47,8 +47,9 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr)
   {
     { memcached_literal_param("version\r\n") },
   };
-  memcached_return_t rc= MEMCACHED_SUCCESS;
 
+  uint32_t success= 0;
+  bool errors_happened= false;
   for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
   {
     memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
@@ -59,73 +60,38 @@ static inline memcached_return_t memcached_version_textual(memcached_st *ptr)
       continue;
     }
 
-    memcached_return_t rrc= memcached_vdo(instance, vector, 1, true);
-    if (memcached_failed(rrc))
+    memcached_return_t rrc;
+    if (memcached_failed(rrc= memcached_vdo(instance, vector, 1, true)))
     {
+      errors_happened= true;
       (void)memcached_set_error(*instance, rrc, MEMCACHED_AT);
-      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-      rc= MEMCACHED_SOME_ERRORS;
-      continue;
-    }
-
-    char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-    rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
-    if (memcached_failed(rrc))
-    {
-      memcached_set_error(*instance, rrc, MEMCACHED_AT);
-      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-      rc= MEMCACHED_SOME_ERRORS;
-      continue;
-    }
-
-    /* Find the space, and then move one past it to copy version */
-    char *response_ptr= index(buffer, ' ');
-    response_ptr++;
-
-    long int version= strtol(response_ptr, (char **)NULL, 10);
-    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
-    {
-      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
-      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-      rc= MEMCACHED_SOME_ERRORS;
       continue;
     }
-    instance->major_version= uint8_t(version);
-
-    response_ptr= index(response_ptr, '.');
-    response_ptr++;
-
-    version= strtol(response_ptr, (char **)NULL, 10);
-    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
-    {
-      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse minor version"));
-      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-      rc= MEMCACHED_SOME_ERRORS;
-      continue;
-    }
-    instance->minor_version= uint8_t(version);
-
-    response_ptr= index(response_ptr, '.');
-    response_ptr++;
+    success++;
+  }
 
-    version= strtol(response_ptr, (char **)NULL, 10);
-    if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
+  if (success)
+  {
+    // Collect the returned items
+    memcached_server_write_instance_st instance;
+    while ((instance= memcached_io_get_readable_server(ptr)))
     {
-      memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
-      instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-      rc= MEMCACHED_SOME_ERRORS;
-      continue;
+      memcached_return_t rrc= memcached_response(instance, NULL);
+      if (memcached_failed(rrc))
+      {
+        memcached_io_reset(instance);
+        errors_happened= true;
+      }
     }
-    instance->micro_version= uint8_t(version);
   }
 
-  return rc;
+  return errors_happened ? MEMCACHED_SOME_ERRORS : MEMCACHED_SUCCESS;
 }
 
 static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
 {
   protocol_binary_request_version request= {};
-  request.message.header.request.magic= PROTOCOL_BINARY_REQ;
+
   request.message.header.request.opcode= PROTOCOL_BINARY_CMD_VERSION;
   request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
 
@@ -134,11 +100,14 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
     { request.bytes, sizeof(request.bytes) }
   };
 
-  memcached_return_t rc= MEMCACHED_SUCCESS;
+  uint32_t success= 0;
+  bool errors_happened= false;
   for (uint32_t x= 0; x < memcached_server_count(ptr); x++) 
   {
     memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
 
+    initialize_binary_request(instance, request.message.header);
+
     if (instance->major_version != UINT8_MAX)
     {
       continue;
@@ -148,66 +117,30 @@ static inline memcached_return_t memcached_version_binary(memcached_st *ptr)
     if (memcached_failed(rrc))
     {
       memcached_io_reset(instance);
-      rc= MEMCACHED_SOME_ERRORS;
+      errors_happened= true;
       continue;
     }
+
+    success++;
   }
 
-  for (uint32_t x= 0; x < memcached_server_count(ptr); x++) 
+  if (success)
   {
-    memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, x);
-
-    if (instance->major_version != UINT8_MAX)
-    {
-      continue;
-    }
-
-    if (memcached_server_response_count(instance) > 0) 
+    // Collect the returned items
+    memcached_server_write_instance_st instance;
+    while ((instance= memcached_io_get_readable_server(ptr)))
     {
       char buffer[32];
-      char *p;
-
       memcached_return_t rrc= memcached_response(instance, buffer, sizeof(buffer), NULL);
       if (memcached_failed(rrc))
       {
         memcached_io_reset(instance);
-        rc= MEMCACHED_SOME_ERRORS;
-        continue;
-      }
-
-      long int version= strtol(buffer, &p, 10);
-      if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX or version == 0)
-      {
-        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse major version"));
-        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-        rc= MEMCACHED_SOME_ERRORS;
-        continue;
-      }
-      instance->major_version= uint8_t(version);
-
-      version= strtol(p +1, &p, 10);
-      if (version == LONG_MIN or version == LONG_MAX or errno == EINVAL or version > UINT8_MAX)
-      {
-        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
-        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-        rc= MEMCACHED_SOME_ERRORS;
-        continue;
-      }
-      instance->minor_version= uint8_t(version);
-
-      version= strtol(p + 1, NULL, 10);
-      if (errno == ERANGE)
-      {
-        memcached_set_error(*instance, MEMCACHED_PROTOCOL_ERROR, MEMCACHED_AT, memcached_literal_param("strtol() failed to parse micro version"));
-        instance->major_version= instance->minor_version= instance->micro_version= UINT8_MAX;
-        rc= MEMCACHED_SOME_ERRORS;
-        continue;
+        errors_happened= true;
       }
-      instance->micro_version= uint8_t(version);
     }
   }
 
-  return rc;
+  return errors_happened ? MEMCACHED_SOME_ERRORS : MEMCACHED_SUCCESS;
 }
 
 memcached_return_t memcached_version(memcached_st *ptr)
@@ -225,12 +158,8 @@ memcached_return_t memcached_version(memcached_st *ptr)
 
   if (memcached_is_binary(ptr))
   {
-    rc= memcached_version_binary(ptr);
-  }
-  else
-  {
-    rc= memcached_version_textual(ptr);      
+    return memcached_version_binary(ptr);
   }
 
-  return rc;
+  return memcached_version_textual(ptr);      
 }