Solved problems introduced by the use of ZOOM.
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 16 Oct 2008 13:02:32 +0000 (15:02 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 16 Oct 2008 13:02:32 +0000 (15:02 +0200)
Solved problems introduced by the use of ZOOM.. Records not processed
at wrong offsets. Records being processed from previous operations (that
should be ignored). Active clients were not set correctly in some cases.
The Client string messages were not in alignment with Client-enums.

src/client.c
src/connection.c

index 37cef18..684e14b 100644 (file)
@@ -83,7 +83,7 @@ struct client {
     char *pquery; // Current search
     char *cqlquery; // used for SRU targets only
     int hits;
-    int records;
+    int record_offset;
     int setno;
     int requestid;            // ID of current outstanding request
     int diagnostic;
@@ -108,9 +108,7 @@ static const char *client_states[] = {
     "Client_Connecting",
     "Client_Connected",
     "Client_Idle",
-    "Client_Initializing",
-    "Client_Searching",
-    "Client_Presenting",
+    "Client_Working",
     "Client_Error",
     "Client_Failed",
     "Client_Disconnected",
@@ -146,7 +144,6 @@ static void client_show_raw_error(struct client *cl, const char *addinfo);
 // Close connection and set state to error
 void client_fatal(struct client *cl)
 {
-    //client_show_raw_error(cl, "client connection failure");
     yaz_log(YLOG_WARN, "Fatal error from %s", client_get_url(cl));
     connection_destroy(cl->connection);
     client_set_state(cl, Client_Error);
@@ -348,7 +345,7 @@ void client_search_response(struct client *cl)
     if (ZOOM_connection_error(link, &error, &addinfo))
     {
         cl->hits = 0;
-        cl->state = Client_Error;
+        client_set_state(cl, Client_Error);
         yaz_log(YLOG_WARN, "Search error %s (%s): %s",
             error, addinfo, client_get_url(cl));
     }
@@ -367,10 +364,9 @@ void client_record_response(struct client *cl)
     ZOOM_resultset resultset = connection_get_resultset(co);
     const char *error, *addinfo;
 
-    yaz_log(YLOG_LOG, "client_record_response");
     if (ZOOM_connection_error(link, &error, &addinfo))
     {
-        cl->state = Client_Error;
+        client_set_state(cl, Client_Error);
         yaz_log(YLOG_WARN, "Search error %s (%s): %s",
             error, addinfo, client_get_url(cl));
     }
@@ -387,18 +383,22 @@ void client_record_response(struct client *cl)
                 cl->show_raw->active = 0;
                 ingest_raw_record(cl, rec);
             }
+            else
+            {
+                yaz_log(YLOG_WARN, "Expected record, but got NULL, offset=%d",
+                        cl->show_raw->position-1);
+            }
         }
         else
         {
-            int offset = cl->records;
+            int offset = cl->record_offset;
             if ((rec = ZOOM_resultset_record(resultset, offset)))
             {
-                yaz_log(YLOG_LOG, "Record with offset %d", offset);
-                
-                cl->records++;
+                cl->record_offset++;
                 if (ZOOM_record_error(rec, &msg, &addinfo, 0))
                     yaz_log(YLOG_WARN, "Record error %s (%s): %s (rec #%d)",
-                            error, addinfo, client_get_url(cl), cl->records);
+                            error, addinfo, client_get_url(cl),
+                            cl->record_offset);
                 else
                 {
                     struct session_database *sdb = client_get_database(cl);
@@ -407,7 +407,7 @@ void client_record_response(struct client *cl)
                     nativesyntax_to_type(sdb, type);
                     if ((xmlrec = ZOOM_record_get(rec, type, NULL)))
                     {
-                        if (ingest_record(cl, xmlrec, cl->records))
+                        if (ingest_record(cl, xmlrec, cl->record_offset))
                         {
                             session_alert_watch(cl->session, SESSION_WATCH_SHOW);
                             session_alert_watch(cl->session, SESSION_WATCH_RECORD);
@@ -420,9 +420,12 @@ void client_record_response(struct client *cl)
                 }
 
             }
+            else
+            {
+                yaz_log(YLOG_WARN, "Expected record, but got NULL, offset=%d",
+                        offset);
+            }
         }
-        if (!rec)
-            yaz_log(YLOG_WARN, "Expected record, but got NULL");
     }
 }
 
@@ -443,8 +446,9 @@ void client_start_search(struct client *cl)
     assert(link);
 
     cl->hits = -1;
-    cl->records = 0;
+    cl->record_offset = 0;
     cl->diagnostic = 0;
+    client_set_state(cl, Client_Working);
 
     if (*opt_piggyback)
         ZOOM_connection_option_set(link, "piggyback", opt_piggyback);
@@ -499,7 +503,7 @@ struct client *client_create(void)
     r->connection = 0;
     r->session = 0;
     r->hits = 0;
-    r->records = 0;
+    r->record_offset = 0;
     r->setno = 0;
     r->requestid = -1;
     r->diagnostic = 0;
@@ -617,7 +621,7 @@ int client_parse_query(struct client *cl, const char *query)
     ccl_qual_rm(&ccl_map);
     if (!cn)
     {
-        cl->state = Client_Error;
+        client_set_state(cl, Client_Error);
         yaz_log(YLOG_WARN, "Failed to parse query for %s",
                          client_get_database(cl)->database->url);
         return -1;
@@ -682,7 +686,7 @@ int client_get_hits(struct client *cl)
 
 int client_get_num_records(struct client *cl)
 {
-    return cl->records;
+    return cl->record_offset;
 }
 
 int client_get_diagnostic(struct client *cl)
index b567114..55b3766 100644 (file)
@@ -72,6 +72,8 @@ struct connection {
     char *ibuf;
     int ibufsize;
     char *zproxy;
+    int set_id_request;
+    int set_id_response;
     enum {
         Conn_Resolving,
         Conn_Connecting,
@@ -114,6 +116,7 @@ void connection_set_resultset(struct connection *co, ZOOM_resultset rs)
 {
     if (co->resultset)
         ZOOM_resultset_destroy(co->resultset);
+    co->set_id_request++;
     co->resultset = rs;
 }
 
@@ -133,12 +136,6 @@ static void remove_connection_from_host(struct connection *con)
     assert(*conp == 0);
 }
 
-void connection_continue(struct connection *co)
-{
-    yaz_log(YLOG_LOG, "connection_continue");
-    iochan_setevent(co->iochan, EVENT_OUTPUT);
-}
-
 // Close connection and recycle structure
 void connection_destroy(struct connection *co)
 {
@@ -187,14 +184,17 @@ static struct connection *connection_create(struct client *cl)
     new->link = 0;
     new->resultset = 0;
     new->state = Conn_Resolving;
+    new->set_id_request = 0;
+    new->set_id_response = 0;
     if (host->ipport)
         connection_connect(new);
     return new;
 }
 
-static void non_block_events(struct connection *co, IOCHAN iochan)
+static void non_block_events(struct connection *co)
 {
     struct client *cl = co->client;
+    IOCHAN iochan = co->iochan;
     ZOOM_connection link = co->link;
     while (1)
     {
@@ -206,7 +206,8 @@ static void non_block_events(struct connection *co, IOCHAN iochan)
         switch (ev) 
         {
         case ZOOM_EVENT_END:
-            client_set_state(co->client, Client_Idle);
+            if (co->set_id_request == co->set_id_response)
+                client_set_state(co->client, Client_Idle);
             break;
         case ZOOM_EVENT_SEND_DATA:
             break;
@@ -226,12 +227,13 @@ static void non_block_events(struct connection *co, IOCHAN iochan)
             iochan_settimeout(iochan, global_parameters.z3950_session_timeout);
             break;
         case ZOOM_EVENT_RECV_SEARCH:
-            yaz_log(YLOG_LOG, "Search response from %s", client_get_url(cl));
-            client_search_response(cl);
+            co->set_id_response++;
+            if (co->set_id_request == co->set_id_response)
+                client_search_response(cl);
             break;
         case ZOOM_EVENT_RECV_RECORD:
-            yaz_log(YLOG_LOG, "Record from %s", client_get_url(cl));
-            client_record_response(cl);
+            if (co->set_id_request == co->set_id_response)
+                client_record_response(cl);
             break;
         default:
             yaz_log(YLOG_LOG, "Unhandled event (%d) from %s",
@@ -240,6 +242,11 @@ static void non_block_events(struct connection *co, IOCHAN iochan)
     }
 }
 
+void connection_continue(struct connection *co)
+{
+    non_block_events(co);
+}
+
 static void connection_handler(IOCHAN iochan, int event)
 {
     struct connection *co = iochan_getdata(iochan);
@@ -269,11 +276,11 @@ static void connection_handler(IOCHAN iochan, int event)
     }
     else
     {
-        non_block_events(co, iochan);
+        non_block_events(co);
 
         ZOOM_connection_fire_event_socket(co->link, event);
         
-        non_block_events(co, iochan);
+        non_block_events(co);
     }
 }
 
@@ -471,6 +478,11 @@ int client_prep_connection(struct client *cl)
             connection_release(co);
             client_set_connection(cl, co);
             co->client = cl;
+#if 0
+            /* tells ZOOM to reconnect if necessary. Disabled becuase
+               the ZOOM_connection_connect flushes the task queue */
+            ZOOM_connection_connect(co->link, 0, 0);
+#endif
         }
         else
             co = connection_create(cl);