Rework of the server connect so that "hostname" lookup does not occur for
authorBrian Aker <brian@tangent.org>
Wed, 14 Nov 2007 05:03:08 +0000 (21:03 -0800)
committerBrian Aker <brian@tangent.org>
Wed, 14 Nov 2007 05:03:08 +0000 (21:03 -0800)
each reconnect.

Some framework for UDP protocol added.

.hgignore
ChangeLog
configure.ac
include/memcached.h
lib/memcached_connect.c
lib/memcached_hosts.c
lib/memcached_io.c
tests/function.c

index ff7c01f6803024c072e6a951de3a5ec64dd90546..1f6ec646e722965f0de0db21028e8db40859659c 100644 (file)
--- a/.hgignore
+++ b/.hgignore
@@ -20,3 +20,6 @@ Makefile(.in)?$
 # Generated man files
 \.1$
 \.3$
+
+# Merged files
+\.orig$
index bda930f29944717776a82129633076fdeb9efbfd..3ce19953399ccd91a1a56e0db4e20ded2947fd97 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,7 @@
   * Modified increment/decrement functions to return uint64_t values
   * Fixed bug in cases where zero length keys were provided
   * Thread cleanup issue in memslap
+  * No hostname lookup on reconnect
 
 0.8 Mon Nov  5 10:40:41 PST 2007
   * Adding support for CRC hash method 
index 58fac5ba012c7ae2d0f9759d14cf8680dd017140..203f7e91e59f9becb562e2f16647c369cbaa79c3 100644 (file)
@@ -6,7 +6,7 @@ MEMCACHED_LIBRARY_NAME=libmemcached
 
 #release versioning
 MEMCACHED_MAJOR_VERSION=0
-MEMCACHED_MINOR_VERSION=8
+MEMCACHED_MINOR_VERSION=9
 MEMCACHED_MICRO_VERSION=0
 
 #API version
index bd056aded456d41163fa1bb5527081f5bc747b86..29195de09076ca69fe9bcc2a658a3f0383dc3902 100644 (file)
@@ -13,6 +13,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <sys/types.h>
+#include <netinet/in.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -107,6 +108,7 @@ struct memcached_server_st {
   char read_buffer[MEMCACHED_MAX_BUFFER];
   size_t read_buffer_length;
   char *read_ptr;
+  struct sockaddr_in servAddr;
   memcached_connection type;
 };
 
@@ -235,6 +237,9 @@ memcached_result_st *memcached_fetch_result(memcached_st *ptr,
 #define memcached_server_list(A) A->hosts
 #define memcached_server_response_count(A,B) A->hosts[B].stack_responses
 
+memcached_return memcached_server_add_udp(memcached_st *ptr, 
+                                          char *hostname,
+                                          unsigned int port);
 memcached_return memcached_server_add_unix_socket(memcached_st *ptr, 
                                                   char *filename);
 memcached_return memcached_server_add(memcached_st *ptr, char *hostname, 
index 025fdf6e00e589532a69f33b50ee790d01eba68b..cbf57fdc6607e19a1b5bcf24188d8b0bafb8dcf5 100644 (file)
@@ -7,6 +7,22 @@
 #include <netinet/tcp.h>
 #include <netdb.h>
 
+static memcached_return set_hostinfo(memcached_server_st *server)
+{
+  struct hostent *h;
+
+  if ((h= gethostbyname(server->hostname)) == NULL)
+  {
+    return MEMCACHED_HOST_LOCKUP_FAILURE;
+  }
+
+  server->servAddr.sin_family= h->h_addrtype;
+  memcpy((char *) &server->servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
+  server->servAddr.sin_port = htons(server->port);
+
+  return MEMCACHED_SUCCESS;
+}
+
 static memcached_return unix_socket_connect(memcached_st *ptr, unsigned int server_key)
 {
   struct sockaddr_un servAddr;
@@ -22,12 +38,14 @@ static memcached_return unix_socket_connect(memcached_st *ptr, unsigned int serv
 
     memset(&servAddr, 0, sizeof (struct sockaddr_un));
     servAddr.sun_family= AF_UNIX;
-    strcpy(servAddr.sun_path, ptr->hosts[server_key].hostname);
+    strcpy(servAddr.sun_path, ptr->hosts[server_key].hostname); /* Copy filename */
 
     addrlen= strlen(servAddr.sun_path) + sizeof(servAddr.sun_family);
 
 test_connect:
-    if (connect(ptr->hosts[server_key].fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
+    if (connect(ptr->hosts[server_key].fd, 
+                (struct sockaddr *)&servAddr,
+                sizeof(servAddr)) < 0)
     {
       switch (errno) {
         /* We are spinning waiting on connect */
@@ -47,25 +65,48 @@ test_connect:
   return MEMCACHED_SUCCESS;
 }
 
-static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
+static memcached_return udp_connect(memcached_st *ptr, unsigned int server_key)
 {
-  struct sockaddr_in servAddr;
-  struct hostent *h;
-
   if (ptr->hosts[server_key].fd == -1)
   {
     /* Old connection junk still is in the structure */
     WATCHPOINT_ASSERT(ptr->hosts[server_key].stack_responses == 0);
 
-    if ((h= gethostbyname(ptr->hosts[server_key].hostname)) == NULL)
+    if (ptr->hosts[server_key].servAddr.sin_family == 0)
     {
-      ptr->cached_errno= h_errno;
-      return MEMCACHED_HOST_LOCKUP_FAILURE;
+      memcached_return rc;
+
+      rc= set_hostinfo(&ptr->hosts[server_key]);
+      if (rc != MEMCACHED_SUCCESS)
+        return rc;
     }
 
-    servAddr.sin_family= h->h_addrtype;
-    memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
-    servAddr.sin_port = htons(ptr->hosts[server_key].port);
+    /* Create the socket */
+    if ((ptr->hosts[server_key].fd= socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+    {
+      ptr->cached_errno= errno;
+      return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+    }
+  }
+
+  return MEMCACHED_SUCCESS;
+}
+
+static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
+{
+  if (ptr->hosts[server_key].fd == -1)
+  {
+    /* Old connection junk still is in the structure */
+    WATCHPOINT_ASSERT(ptr->hosts[server_key].stack_responses == 0);
+
+    if (ptr->hosts[server_key].servAddr.sin_family == 0)
+    {
+      memcached_return rc;
+
+      rc= set_hostinfo(&ptr->hosts[server_key]);
+      if (rc != MEMCACHED_SUCCESS)
+        return rc;
+    }
 
     /* Create the socket */
     if ((ptr->hosts[server_key].fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
@@ -106,7 +147,9 @@ static memcached_return tcp_connect(memcached_st *ptr, unsigned int server_key)
 
     /* connect to server */
 test_connect:
-    if (connect(ptr->hosts[server_key].fd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
+    if (connect(ptr->hosts[server_key].fd, 
+                (struct sockaddr *)&ptr->hosts[server_key].servAddr, 
+                sizeof(struct sockaddr)) < 0)
     {
       switch (errno) {
         /* We are spinning waiting on connect */
@@ -142,7 +185,25 @@ memcached_return memcached_connect(memcached_st *ptr, unsigned int server_key)
 
   /* We need to clean up the multi startup piece */
   if (server_key)
+  {
     rc= tcp_connect(ptr, server_key);
+    switch (ptr->hosts[server_key].type)
+    {
+    case MEMCACHED_CONNECTION_UNKNOWN:
+      WATCHPOINT_ASSERT(0);
+      rc= MEMCACHED_NOT_SUPPORTED;
+      break;
+    case MEMCACHED_CONNECTION_UDP:
+      rc= udp_connect(ptr, server_key);
+      break;
+    case MEMCACHED_CONNECTION_TCP:
+      rc= tcp_connect(ptr, server_key);
+      break;
+    case MEMCACHED_CONNECTION_UNIX_SOCKET:
+      rc= unix_socket_connect(ptr, server_key);
+      break;
+    }
+  }
   else
   {
     unsigned int x;
@@ -156,10 +217,12 @@ memcached_return memcached_connect(memcached_st *ptr, unsigned int server_key)
       switch (ptr->hosts[x].type)
       {
       case MEMCACHED_CONNECTION_UNKNOWN:
-      case MEMCACHED_CONNECTION_UDP:
         WATCHPOINT_ASSERT(0);
         possible_rc= MEMCACHED_NOT_SUPPORTED;
         break;
+      case MEMCACHED_CONNECTION_UDP:
+        possible_rc= udp_connect(ptr, x);
+        break;
       case MEMCACHED_CONNECTION_TCP:
         possible_rc= tcp_connect(ptr, x);
         break;
index c77e5583eb2d9caa7146dee6a998a6cc9f47768f..f16052b345d627a67d2bba9b7f0245c065a7beac 100644 (file)
@@ -9,14 +9,11 @@ static memcached_return server_add(memcached_st *ptr, char *hostname,
 static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port,
                        memcached_connection type)
 {
-  host->stack_responses= 0;
-  host->cursor_active= 0;
+  memset(host,  0, sizeof(memcached_server_st));
   host->hostname= new_hostname;
   host->port= port;
   host->fd= -1;
   host->type= type;
-  host->write_buffer_offset= 0;
-  host->read_buffer_length= 0;
   host->read_ptr= host->read_buffer;
 }
 
@@ -64,7 +61,22 @@ memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filen
   return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET);
 }
 
-memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port)
+memcached_return memcached_server_add_udp(memcached_st *ptr, 
+                                          char *hostname,
+                                          unsigned int port)
+{
+  if (!port)
+    port= MEMCACHED_DEFAULT_PORT; 
+
+  if (!hostname)
+    hostname= "localhost"; 
+
+  return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_UDP);
+}
+
+memcached_return memcached_server_add(memcached_st *ptr, 
+                                      char *hostname, 
+                                      unsigned int port)
 {
   if (!port)
     port= MEMCACHED_DEFAULT_PORT; 
index 473b8881dc2bd61f1d6703d948ff35887da307e2..c0215ac08f917d83249a0c74dcfebd277d2a894d 100644 (file)
@@ -140,24 +140,38 @@ ssize_t memcached_io_flush(memcached_st *ptr, unsigned int server_key)
     }
 
     sent_length= 0;
-    if ((ssize_t)(sent_length= write(ptr->hosts[server_key].fd, write_ptr, 
-                                     write_length)) == -1)
+    if (ptr->hosts[server_key].type == MEMCACHED_CONNECTION_UDP)
     {
-      switch (errno)
+
+      sent_length= sendto(ptr->hosts[server_key].fd, write_ptr, write_length,
+                          0, 0, 0);
+      /*
+      rc = sendto(sd, argv[i], strlen(argv[i])+1, 0,
+                  (struct sockaddr *) &remoteServAddr,
+                  sizeof(remoteServAddr));
+                */
+    }
+    else
+    {
+      if ((ssize_t)(sent_length= write(ptr->hosts[server_key].fd, write_ptr, 
+                                       write_length)) == -1)
       {
-      case ENOBUFS:
-      case EAGAIN:
-        WATCHPOINT;
-        continue;
-        if (loop < 100)
+        switch (errno)
         {
-          loop++;
-          break;
+        case ENOBUFS:
+        case EAGAIN:
+          WATCHPOINT;
+          continue;
+          if (loop < 100)
+          {
+            loop++;
+            break;
+          }
+          /* Yes, we want to fall through */
+        default:
+          ptr->cached_errno= errno;
+          return -1;
         }
-        /* Yes, we want to fall through */
-      default:
-        ptr->cached_errno= errno;
-        return -1;
       }
     }
 
index 1e2c6f075646dd6ed9dc03b658a1431e60f1362f..7d2de7032d281f8cf439426d5ace817d0d2ffa6a 100644 (file)
@@ -1379,6 +1379,22 @@ memcached_return pre_unix_socket(memcached_st *memc)
   return rc;
 }
 
+memcached_return pre_udp(memcached_st *memc)
+{
+  memcached_return rc;
+
+  memcached_server_list_free(memc->hosts);
+  memc->hosts= NULL;
+  memc->number_of_hosts= 0;
+
+  if (0)
+    return MEMCACHED_FAILURE;
+
+  rc= memcached_server_add_udp(memc, "localhost", MEMCACHED_DEFAULT_PORT);
+
+  return rc;
+}
+
 memcached_return pre_nodelay(memcached_st *memc)
 {
   memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL);
@@ -1467,6 +1483,7 @@ collection_st collection[] ={
   {"ketama", pre_hash_ketama, 0, tests},
   {"unix_socket", pre_unix_socket, 0, tests},
   {"unix_socket_nodelay", pre_nodelay, 0, tests},
+//  {"udp", pre_udp, 0, tests},
   {"string", 0, 0, string_tests},
   {"result", 0, 0, result_tests},
   {"user", 0, 0, user_tests},