Connections now wait for hosts to be resolved. Delayed connect attempt
authorAdam Dickmeiss <adam@indexdata.dk>
Sun, 22 Apr 2007 16:41:42 +0000 (16:41 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Sun, 22 Apr 2007 16:41:42 +0000 (16:41 +0000)
is handled by connect_resolver_host. All connection with bad addresses
(unresolved ones) are destroyed with connection_destroy. Connect
failures leave the connections in the open. If that's to be changed
connection_destroy should be called if connection_connect returns -1.

src/getaddrinfo.c
src/logic.c
src/pazpar2.h

index 26557d8..4216ab5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: getaddrinfo.c,v 1.1 2007-04-21 12:00:54 adam Exp $
+/* $Id: getaddrinfo.c,v 1.2 2007-04-22 16:41:42 adam Exp $
    Copyright (c) 2006-2007, Index Data.
 
 This file is part of Pazpar2.
@@ -116,6 +116,7 @@ void iochan_handler(struct iochan *i, int event)
         else
             yaz_log(log_level, "unresolved result");
         w->host->ipport = w->ipport;
+        connect_resolver_host(w->host);
         xfree(w);
     }
 }
@@ -144,7 +145,7 @@ static void getaddrinfo_start(void)
 int host_getaddrinfo(struct host *host)
 {
     struct work *w = xmalloc(sizeof(*w));
-    int use_thread = 1;
+    int use_thread = 1; /* =0 to disable threading entirely */
 
     w->hostport = host->hostport;
     w->ipport = 0;
index 5ca1dbe..bce0ad1 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: logic.c,v 1.17 2007-04-22 15:07:10 adam Exp $
+/* $Id: logic.c,v 1.18 2007-04-22 16:41:42 adam Exp $
    Copyright (c) 2006-2007, Index Data.
 
 This file is part of Pazpar2.
@@ -1100,8 +1100,12 @@ static void connection_release(struct connection *co)
 static void connection_destroy(struct connection *co)
 {
     struct host *h = co->host;
-    cs_close(co->link);
-    iochan_destroy(co->iochan);
+    
+    if (co->link)
+    {
+        cs_close(co->link);
+        iochan_destroy(co->iochan);
+    }
 
     yaz_log(YLOG_DEBUG, "Connection destroy %s", co->host->hostport);
     if (h->connections == co)
@@ -1126,61 +1130,103 @@ static void connection_destroy(struct connection *co)
     connection_freelist = co;
 }
 
-
-// Creates a new connection for client, associated with the host of 
-// client's database
-static struct connection *connection_create(struct client *cl)
+static int connection_connect(struct connection *con)
 {
-    struct connection *new;
-    COMSTACK link; 
-    int res;
+    COMSTACK link = 0;
+    struct client *cl = con->client;
+    struct host *host = con->host;
     void *addr;
-    struct host *host = cl->database->database->host;
+    int res;
 
-    if (!host->ipport)
-    {
-        yaz_log(YLOG_WARN, "Not yet resolved: %s",
-                cl->database->database->url);
-        return 0;
-    }
+    assert(host->ipport);
+    assert(cl);
 
     if (!(link = cs_create(tcpip_type, 0, PROTO_Z3950)))
-        {
-            yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to create comstack");
-            exit(1);
-        }
+    {
+        yaz_log(YLOG_FATAL|YLOG_ERRNO, "Failed to create comstack");
+        exit(1);
+    }
     
     if (0 == strlen(global_parameters.zproxy_override)){
         /* no Z39.50 proxy needed - direct connect */
         yaz_log(YLOG_DEBUG, "Connection create %s", cl->database->database->url);
         
         if (!(addr = cs_straddr(link, host->ipport)))
-            {
-                yaz_log(YLOG_WARN|YLOG_ERRNO, 
-                        "Lookup of IP address %s failed", host->ipport);
-                return 0;
-            }
-    
+        {
+            yaz_log(YLOG_WARN|YLOG_ERRNO, 
+                    "Lookup of IP address %s failed", host->ipport);
+            return -1;
+        }
+        
     } else {
         /* Z39.50 proxy connect */
         yaz_log(YLOG_DEBUG, "Connection create %s proxy %s", 
                 cl->database->database->url, global_parameters.zproxy_override);
-
+        
         if (!(addr = cs_straddr(link, global_parameters.zproxy_override)))
-            {
-                yaz_log(YLOG_WARN|YLOG_ERRNO, 
-                        "Lookup of IP address %s failed", 
-                        global_parameters.zproxy_override);
-                return 0;
-            }
+        {
+            yaz_log(YLOG_WARN|YLOG_ERRNO, 
+                    "Lookup of IP address %s failed", 
+                    global_parameters.zproxy_override);
+            return -1;
+        }
     }
-
+    
     res = cs_connect(link, addr);
     if (res < 0)
     {
         yaz_log(YLOG_WARN|YLOG_ERRNO, "cs_connect %s", cl->database->database->url);
-        return 0;
+        return -1;
+    }
+    con->link = link;
+    con->state = Conn_Connecting;
+    con->iochan = iochan_create(cs_fileno(link), connection_handler, 0);
+    iochan_setdata(con->iochan, con);
+    pazpar2_add_channel(con->iochan);
+
+    /* this fragment is bad DRY: from client_prep_connection */
+    cl->state = Client_Connecting;
+    iochan_setflag(con->iochan, EVENT_OUTPUT);
+    return 0;
+}
+
+void connect_resolver_host(struct host *host)
+{
+    struct connection *con = host->connections;
+
+    while (con)
+    {
+        if (con->state == Conn_Resolving)
+        {
+            if (!host->ipport) /* unresolved */
+            {
+                connection_destroy(con);
+                /* start all over .. at some point it will be NULL */
+                con = host->connections;
+            }
+            else if (!con->client)
+            {
+                yaz_log(YLOG_WARN, "connect_unresolved_host : ophan client");
+                connection_destroy(con);
+                /* start all over .. at some point it will be NULL */
+                con = host->connections;
+            }
+            else
+            {
+                connection_connect(con);
+                con = con->next;
+            }
+        }
     }
+}
+
+
+// Creates a new connection for client, associated with the host of 
+// client's database
+static struct connection *connection_create(struct client *cl)
+{
+    struct connection *new;
+    struct host *host = cl->database->database->host;
 
     if ((new = connection_freelist))
         connection_freelist = new->next;
@@ -1190,17 +1236,15 @@ static struct connection *connection_create(struct client *cl)
         new->ibuf = 0;
         new->ibufsize = 0;
     }
-    new->state = Conn_Connecting;
     new->host = host;
     new->next = new->host->connections;
     new->host->connections = new;
     new->client = cl;
     cl->connection = new;
-    new->link = link;
-
-    new->iochan = iochan_create(cs_fileno(link), connection_handler, 0);
-    iochan_setdata(new->iochan, new);
-    pazpar2_add_channel(new->iochan);
+    new->link = 0;
+    new->state = Conn_Resolving;
+    if (host->ipport)
+        connection_connect(new);
     return new;
 }
 
index ef910ab..9d42c37 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pazpar2.h,v 1.32 2007-04-21 12:00:54 adam Exp $
+/* $Id: pazpar2.h,v 1.33 2007-04-22 16:41:42 adam Exp $
    Copyright (c) 2006-2007, Index Data.
 
 This file is part of Pazpar2.
@@ -83,6 +83,7 @@ struct connection {
     char *ibuf;
     int ibufsize;
     enum {
+        Conn_Resolving,
         Conn_Connecting,
         Conn_Open,
         Conn_Waiting,
@@ -238,6 +239,7 @@ void pazpar2_add_channel(IOCHAN c);
 void pazpar2_event_loop(void);
 
 int host_getaddrinfo(struct host *host);
+void connect_resolver_host(struct host *host);
 
 #endif