chiark / gitweb /
fix so successful only connect really not blocker for another connect; lowvol in...
[inn-innduct.git] / backends / innduct.c
index 772fc89c0079e99be2146d40a53fd7e65bcf344c..c42771d885729dae0115eba0ff00f06d04c62e69 100644 (file)
@@ -391,8 +391,8 @@ static int backlog_spontrescan_periods=300;
 static int spontaneous_flush_periods=100000;
 static int max_separated_periods=2000;
 static int need_activity_periods=1000;
-static int recentact_thresh=3;
-static int recentact_periods=1000;
+static int lowvol_thresh=3;
+static int lowvol_periods=1000;
 
 static double max_bad_data_ratio= 1; /* conv'd from percentage by main */
 static int max_bad_data_initial= 30;
@@ -511,7 +511,8 @@ struct Conn {
   ISNODE(Conn);
   int fd; /* may be 0, meaning closed (during construction/destruction) */
   oop_read *rd; /* likewise */
-  int max_queue, stream, quitting;
+  int max_queue, stream;
+  const char *quitting;
   int since_activity; /* periods */
   ArticleList waiting; /* not yet told peer */
   ArticleList priority; /* peer says send it now */
@@ -530,9 +531,9 @@ static ConnList conns;
 static char *path_lock, *path_flushing, *path_defer, *path_dump;
 static char *globpat_backlog;
 static pid_t self_pid;
-static int *recentact_perperiod;
-static int recentact_circptr;
-static int recentact_total;
+static int *lowvol_perperiod;
+static int lowvol_circptr;
+static int lowvol_total;
 
 /* statemc_init initialises */
 static StateMachineState sms;
@@ -1175,7 +1176,7 @@ static void conn_idle_close(Conn *conn, const char *why) {
     assert(r<=todo);
     todo -= r;
     if (!todo) {
-      conn->quitting= 1;
+      conn->quitting= why;
       conn->since_activity= 0;
       debug("C%d is idle (%s), quitting", conn->fd, why);
       break;
@@ -1190,11 +1191,11 @@ static void conn_idle_close(Conn *conn, const char *why) {
 static void check_idle_conns(void) {
   Conn *conn;
 
-  int veryrecentact= recentact_perperiod[recentact_circptr];
-  recentact_circptr++;
-  recentact_circptr %= recentact_periods;
-  recentact_total -= recentact_perperiod[recentact_circptr];
-  recentact_perperiod[recentact_circptr]= 0;
+  int verylowvol= lowvol_perperiod[lowvol_circptr];
+  lowvol_circptr++;
+  lowvol_circptr %= lowvol_periods;
+  lowvol_total -= lowvol_perperiod[lowvol_circptr];
+  lowvol_perperiod[lowvol_circptr]= 0;
 
   FOR_CONN(conn)
     conn->since_activity++;
@@ -1205,7 +1206,8 @@ static void check_idle_conns(void) {
 
     /* We need to shut this down */
     if (conn->quitting)
-      connfail(conn,"timed out waiting for response to QUIT");
+      connfail(conn,"timed out waiting for response to QUIT (%s)",
+              conn->quitting);
     else if (conn->sent.count)
       connfail(conn,"timed out waiting for responses");
     else if (conn->waiting.count || conn->priority.count)
@@ -1220,9 +1222,9 @@ static void check_idle_conns(void) {
   }
 
   conn= LIST_HEAD(conns);
-  if (!veryrecentact &&
+  if (!verylowvol &&
       conns.count==1 &&
-      recentact_total+veryrecentact < recentact_thresh &&
+      lowvol_total+verylowvol < lowvol_thresh &&
       !conn_busy(conn))
     conn_idle_close(conn, "low volume");
 }  
@@ -1233,7 +1235,6 @@ static pid_t connecting_child;
 static int connecting_fdpass_sock;
 
 static void connect_attempt_discard(void) {
-  reconnect_blocking_event();
   if (connecting_child) {
     int status= xwaitpid(&connecting_child, "connect");
     if (!(WIFEXITED(status) ||
@@ -1358,6 +1359,7 @@ static void *connchild_event(oop_source *lp, int fd, oop_event e, void *u) {
  x:
   conn_dispose(conn);
   connect_attempt_discard();
+  reconnect_blocking_event();
   return OOP_CONTINUE;
 }
 
@@ -1372,6 +1374,7 @@ static void connect_start(void) {
   assert(!connecting_fdpass_sock);
 
   info("starting connection attempt");
+  int ok_until_connect= until_connect;
   reconnect_blocking_event();
 
   int socks[2];
@@ -1465,6 +1468,9 @@ static void connect_start(void) {
   connecting_fdpass_sock= socks[0];
   xsetnonblock(connecting_fdpass_sock, 1);
   on_fd_read_except(connecting_fdpass_sock, connchild_event);
+
+  if (!conns.count)
+    until_connect= ok_until_connect;
 }
 
 /*---------- assigning articles to conns, and transmitting ----------*/
@@ -1517,7 +1523,7 @@ static void check_assign_articles(void) {
        Article *art= dequeue(0);
        if (!art) break;
        LIST_ADDTAIL(use->waiting, art);
-       recentact_perperiod[recentact_circptr]++;
+       lowvol_perperiod[lowvol_circptr]++;
        spare--;
       }
       conn_maybe_write(use);
@@ -1635,6 +1641,7 @@ static void autodefer_input_file_articles(InputFile *ipf) {
 }
 
 static void autodefer_input_file(InputFile *ipf) {
+  static const char *const abandon= "stuck";
   ipf->autodefer= 0;
 
   autodefer_input_file_articles(ipf);
@@ -1645,11 +1652,11 @@ static void autodefer_input_file(InputFile *ipf) {
       if (has_article_in(&walk->waiting,  ipf) ||
          has_article_in(&walk->priority, ipf) ||
          has_article_in(&walk->sent,     ipf))
-       walk->quitting= -1;
+       walk->quitting= abandon;
     }
     while (ipf->inprogress) {
       FOR_CONN(walk)
-       if (walk->quitting < 0) goto found;
+       if (walk->quitting == abandon) goto found;
       abort(); /* where are they ?? */
 
     found:
@@ -1947,11 +1954,12 @@ static void *peer_rd_ok(oop_source *lp, oop_read *oread, oop_rd_event ev,
 
   if (conn->quitting) {
     if (code!=205 && code!=400) {
-      connfail(conn, "peer gave unexpected response to QUIT: %s", sani);
+      connfail(conn, "peer gave unexpected response to QUIT (%s): %s",
+              conn->quitting, sani);
     } else {
       LIST_REMOVE(conns,conn);
-      notice("C%d (now %d) idle connection closed by us",
-            conn->fd, conns.count);
+      notice("C%d (now %d) idle connection closed (%s)",
+            conn->fd, conns.count, conn->quitting);
       assert(!busy);
       conn_dispose(conn);
     }
@@ -3303,11 +3311,11 @@ static void period(void) {
   debug("PERIOD"
        " sms=%s[%d] conns=%d until_connect=%d"
        " input_files main:%s flushing:%s backlog:%s[%d]"
-       " children connecting=%ld inndcomm=%ld"
+       " children connecting=%ld inndcomm=%ld lowvol_total=%d"
        ,
        sms_names[sms], until_flush, conns.count, until_connect,
        dipf_main, dipf_flushing, dipf_backlog, until_backlog_nextscan,
-       (long)connecting_child, (long)inndcomm_child
+       (long)connecting_child, (long)inndcomm_child, lowvol_total
        );
 
   free(dipf_main);
@@ -3398,6 +3406,17 @@ CCMD(dump) {
   DUMPV("%d", , cli_master);
   fprintf(f,"\n");
 
+  fprintf(f,"lowvol ");
+  DUMPV("%d", , lowvol_circptr);
+  DUMPV("%d", , lowvol_total);
+  fprintf(f,":");
+  for (i=0; i<lowvol_periods; i++) {
+    fprintf(f," ");
+    if (i==lowvol_circptr) fprintf(f,"*");
+    fprintf(f,"%d",lowvol_perperiod[i]);
+  }
+  fprintf(f,"\n");
+
   fprintf(f,"filemon ");
   filemon_method_dump_info(f);
 
@@ -3412,7 +3431,7 @@ CCMD(dump) {
 
     fprintf(f,"C%d",conn->fd);
     DUMPV("%p",conn->,rd);             DUMPV("%d",conn->,max_queue);
-    DUMPV("%d",conn->,stream);         DUMPV("%d",conn->,quitting);
+    DUMPV("%d",conn->,stream);         DUMPV("\"%s\"",conn->,quitting);
     DUMPV("%d",conn->,since_activity);
     fprintf(f,"\n");
 
@@ -3650,8 +3669,8 @@ static const Option innduct_options[]= {
 {0,"max-flush-interval",     "PERIOD", &spontaneous_flush_periods,op_seconds },
 {0,"flush-finish-timeout",   "PERIOD", &max_separated_periods,    op_seconds },
 {0,"idle-timeout",           "PERIOD", &need_activity_periods,    op_seconds },
-{0,"low-volume-thresh",      "PERIOD", &recentact_thresh,         op_integer },
-{0,"low-volume-window",      "PERIOD", &recentact_periods,        op_seconds },
+{0,"low-volume-thresh",      "PERIOD", &lowvol_thresh,            op_integer },
+{0,"low-volume-window",      "PERIOD", &lowvol_periods,           op_seconds },
 
 {0,"max-bad-input-data-ratio","PERCENT", &max_bad_data_ratio,   op_double    },
 {0,"max-bad-input-data-init", "PERCENT", &max_bad_data_initial, op_integer   },
@@ -3725,7 +3744,7 @@ int main(int argc, char **argv) {
   convert_to_periods_rndup(&spontaneous_flush_periods);
   convert_to_periods_rndup(&max_separated_periods);
   convert_to_periods_rndup(&need_activity_periods);
-  convert_to_periods_rndup(&recentact_periods);
+  convert_to_periods_rndup(&lowvol_periods);
 
   if (max_bad_data_ratio < 0 || max_bad_data_ratio > 100)
     badusage("bad input data ratio must be between 0..100");
@@ -3761,10 +3780,10 @@ int main(int argc, char **argv) {
       badusage("feed filename may not contain metacharacter %c",c);
 
   int i;
-  recentact_perperiod= xcalloc(sizeof(*recentact_perperiod),recentact_periods);
-  for (i=0; i<recentact_periods; i++) {
-    recentact_perperiod[i]= recentact_thresh;
-    recentact_total += recentact_thresh;
+  lowvol_perperiod= xcalloc(sizeof(*lowvol_perperiod), lowvol_periods);
+  for (i=0; i<lowvol_periods; i++) {
+    lowvol_perperiod[i]= lowvol_thresh;
+    lowvol_total += lowvol_thresh;
   }
 
   /* set things up */