chiark / gitweb /
New 'new_max' configuration bounds the number of tracks that 'new'
authorRichard Kettlewell <richard@fanticule>
Tue, 1 Jan 2008 13:47:50 +0000 (13:47 +0000)
committerRichard Kettlewell <richard@fanticule>
Tue, 1 Jan 2008 13:47:50 +0000 (13:47 +0000)
will return.  Previously a new installation with many tracks would
attempt to return thousands of tracks, busting event.c's buffer limit.

Made event.c buffer connection abandonment reporting less chatty.

doc/disorder_config.5.in
doc/disorder_protocol.5.in
lib/configuration.c
lib/configuration.h
lib/event.c
server/server.c

index a2e638395e4c61ded25d2d26b1011ce7213b6251..3b2e5a982e29ec3a2c988a5f58f271f1954cc005 100644 (file)
@@ -442,6 +442,10 @@ namepart artist "/([^/]+)/[^/]+/[^/]+$"                    $1 *
 namepart ext    "(\\.[a-zA-Z0-9]+)$"                        $1 *
 .fi
 .TP
+.B new_max \fIMAX\fR
+The maximum number of tracks to list when reporting newly noticed tracks.  The
+default is 100.
+.TP
 .B nice_rescan \fIPRIORITY\fR
 Set the recan subprocess priority.  The default is 10.
 .IP
index 7cb69a7b68cf2983dba6af66be2f6931b8898209..2d2d64400ea86ffb8c0899398a619e5821a59fb5 100644 (file)
@@ -148,7 +148,8 @@ depending on how the tracks came to be added to the queue.
 .TP
 .B new \fR[\fIMAX\fR]
 Send the most recently added \fIMAX\fR tracks in a response body.  If the
-argument is ommitted, all recently added tracks are listed.
+argument is ommitted, the \fBnew_max\fR most recent tracks are listed (see
+\fBdisorder_config\fR(5)).
 .TP
 .B nop
 Do nothing.  Used by
index 3cf276e821d972ef321b89129082cd11cd2a1521..67f4f89d5b6150dfa96b6f2af95ed3a1e4eef8c1 100644 (file)
@@ -946,6 +946,7 @@ static const struct conf conf[] = {
   { C(multicast_loop),   &type_boolean,          validate_any },
   { C(multicast_ttl),    &type_integer,          validate_non_negative },
   { C(namepart),         &type_namepart,         validate_any },
+  { C(new_max),          &type_integer,          validate_positive },
   { C2(nice, nice_rescan), &type_integer,        validate_non_negative },
   { C(nice_rescan),      &type_integer,          validate_non_negative },
   { C(nice_server),      &type_integer,          validate_any },
@@ -1188,6 +1189,7 @@ static struct config *config_default(void) {
   c->cookie_login_lifetime = 86400;
   c->cookie_key_lifetime = 86400 * 7;
   c->smtp_server = xstrdup("127.0.0.1");
+  c->new_max = 100;
   /* Default stopwords */
   if(config_set(&cs, (int)NDEFAULT_STOPWORDS, (char **)default_stopwords))
     exit(1);
index f965bbd972a8f8232dc3f3b27311243387e88316..aa0682d100c87e48a67ff7b600509321113b8a44 100644 (file)
@@ -261,6 +261,9 @@ struct config {
 
   /** @brief Origin address for outbound mail */
   char *mail_sender;
+
+  /** @brief Maximum number of tracks in response to 'new' */
+  long new_max;
   
   /* derived values: */
   int nparts;                          /* number of distinct name parts */
index 3618bf41c7b4e4e9cd853339f597361f512f1694..d3a0c33252fb68d31e1e5533195519f465ff2409 100644 (file)
@@ -930,6 +930,9 @@ struct ev_writer {
 
   /** @brief Tied reader or 0 */
   ev_reader *reader;
+
+  /** @brief Set when abandoned */
+  int abandoned;
 };
 
 /** @brief State structure for a buffered reader */
@@ -998,9 +1001,12 @@ static int writer_timebound_exceeded(ev_source *ev,
                                     void *u) {
   ev_writer *const w = u;
 
-  error(0, "abandoning writer %s because no writes within %ds",
-       w->what, w->timebound);
-  w->error = ETIMEDOUT;
+  if(!w->abandoned) {
+    w->abandoned = 1;
+    error(0, "abandoning writer '%s' because no writes within %ds",
+         w->what, w->timebound);
+    w->error = ETIMEDOUT;
+  }
   return writer_shutdown(ev, now, u);
 }
 
@@ -1075,11 +1081,15 @@ static int ev_writer_write(struct sink *sk, const void *s, int n) {
     /* The new buffer contents will exceed the space bound.  We assume that the
      * remote client has gone away and TCP hasn't noticed yet, or that it's got
      * hopelessly stuck. */
-    error(0, "abandoning writer %s because buffer has reached %td bytes",
-         w->what, w->b.end - w->b.start);
-    ev_fd_disable(w->ev, ev_write, w->fd);
-    w->error = EPIPE;
-    return ev_timeout(w->ev, 0, 0, writer_shutdown, w);
+    if(!w->abandoned) {
+      w->abandoned = 1;
+      error(0, "abandoning writer '%s' because buffer has reached %td bytes",
+           w->what, w->b.end - w->b.start);
+      ev_fd_disable(w->ev, ev_write, w->fd);
+      w->error = EPIPE;
+      return ev_timeout(w->ev, 0, 0, writer_shutdown, w);
+    } else
+      return 0;
   }
   /* Make sure there is space */
   buffer_space(&w->b, n);
index a7dee9904555a281dabc0de6850b753a542cf3bd..69129c9be600b86873f81957a6eb065186cc2b56 100644 (file)
@@ -995,9 +995,18 @@ static int c_nop(struct conn *c,
 static int c_new(struct conn *c,
                 char **vec,
                 int nvec) {
-  char **tracks = trackdb_new(0, nvec > 0 ? atoi(vec[0]) : INT_MAX);
+  int max, n;
+  char **tracks;
 
+  if(nvec > 0)
+    max = atoi(vec[0]);
+  else
+    max = INT_MAX;
+  if(max <= 0 || max > config->new_max)
+    max = config->new_max;
+  tracks = trackdb_new(0, max);
   sink_printf(ev_writer_sink(c->w), "253 New track list follows\n");
+  n = 0;
   while(*tracks) {
     sink_printf(ev_writer_sink(c->w), "%s%s\n",
                **tracks == '.' ? "." : "", *tracks);