Blob Blame History Raw
From c1a7c87fb9710fb29d699d1f39d0da19caf98da0 Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Sat, 11 Jun 2022 12:34:02 +0100
Subject: [PATCH] rate: Allow burstiness to be controlled

Previously it was fixed at 2.0 seconds.  Allowing it to be adjusted
upwards could help with large, lumpy requests.

(cherry picked from commit f79e951c20510381d5cd83c203c670874a4978f4)
---
 filters/rate/nbdkit-rate-filter.pod | 12 ++++++++++--
 filters/rate/rate.c                 | 20 +++++++++++++-------
 tests/test-rate.sh                  |  2 +-
 3 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/filters/rate/nbdkit-rate-filter.pod b/filters/rate/nbdkit-rate-filter.pod
index 8956e641..09ce7dbc 100644
--- a/filters/rate/nbdkit-rate-filter.pod
+++ b/filters/rate/nbdkit-rate-filter.pod
@@ -9,6 +9,7 @@ nbdkit-rate-filter - limit bandwidth by connection or server
                       [connection-rate=BITSPERSEC]
                       [rate-file=FILENAME]
                       [connection-rate-file=FILENAME]
+                      [burstiness=SECS]
 
 =head1 DESCRIPTION
 
@@ -63,6 +64,13 @@ Limit total bandwidth across all connections to C<BITSPERSEC>.
 Adjust the per-connection or total bandwidth dynamically by writing
 C<BITSPERSEC> into C<FILENAME>.  See L</DYNAMIC ADJUSTMENT> below.
 
+=item B<burstiness=>SECS
+
+Control the bucket capacity, expressed as a length of time in
+"rate-equivalent seconds" that the client is allowed to burst for
+after a period of inactivity.  The default is 2.0 seconds.  It's not
+recommended to set this smaller than the default.
+
 =back
 
 C<BITSPERSEC> can be specified as a simple number, or you can use a
@@ -105,8 +113,8 @@ If the size of requests made by your client is much larger than the
 rate limit then you can see long, lumpy sleeps in this filter.  In the
 future we may modify the filter to break up large requests
 automatically in order to limit the length of sleeps.  Placing the
-L<nbdkit-blocksize-filter(1)> in front of this filter may help in the
-meantime.
+L<nbdkit-blocksize-filter(1)> in front of this filter, or adjusting
+C<burstiness> upwards may help.
 
 =head1 FILES
 
diff --git a/filters/rate/rate.c b/filters/rate/rate.c
index 1a70d212..26082f8c 100644
--- a/filters/rate/rate.c
+++ b/filters/rate/rate.c
@@ -68,10 +68,9 @@ static char *rate_file = NULL;
 
 /* Bucket capacity controls the burst rate.  It is expressed as the
  * length of time in "rate-equivalent seconds" that the client can
- * burst for after a period of inactivity.  This could be adjustable
- * in future.
+ * burst for after a period of inactivity.
  */
-#define BUCKET_CAPACITY 2.0
+static double bucket_capacity = 2.0 /* seconds */;
 
 /* Global read and write buckets. */
 static struct bucket read_bucket;
@@ -142,6 +141,13 @@ rate_config (nbdkit_next_config *next, nbdkit_backend *nxdata,
       return -1;
     return 0;
   }
+  else if (strcmp (key, "burstiness") == 0) {
+    if (sscanf (value, "%lg", &bucket_capacity) != 1) {
+      nbdkit_error ("burstiness must be a floating point number (seconds)");
+      return -1;
+    }
+    return 0;
+  }
   else
     return next (nxdata, key, value);
 }
@@ -150,8 +156,8 @@ static int
 rate_get_ready (int thread_model)
 {
   /* Initialize the global buckets. */
-  bucket_init (&read_bucket, rate, BUCKET_CAPACITY);
-  bucket_init (&write_bucket, rate, BUCKET_CAPACITY);
+  bucket_init (&read_bucket, rate, bucket_capacity);
+  bucket_init (&write_bucket, rate, bucket_capacity);
 
   return 0;
 }
@@ -178,8 +184,8 @@ rate_open (nbdkit_next_open *next, nbdkit_context *nxdata,
     return NULL;
   }
 
-  bucket_init (&h->read_bucket, connection_rate, BUCKET_CAPACITY);
-  bucket_init (&h->write_bucket, connection_rate, BUCKET_CAPACITY);
+  bucket_init (&h->read_bucket, connection_rate, bucket_capacity);
+  bucket_init (&h->write_bucket, connection_rate, bucket_capacity);
   pthread_mutex_init (&h->read_bucket_lock, NULL);
   pthread_mutex_init (&h->write_bucket_lock, NULL);
 
diff --git a/tests/test-rate.sh b/tests/test-rate.sh
index 7305c928..ff781c21 100755
--- a/tests/test-rate.sh
+++ b/tests/test-rate.sh
@@ -56,7 +56,7 @@ nbdkit -U - \
        --filter=blocksize --filter=rate \
        pattern 25M \
        maxdata=65536 \
-       rate=10M \
+       rate=10M burstiness=2.0 \
        --run 'nbdcopy "$uri" rate.img'
 end_t=$SECONDS
 
-- 
2.31.1