@@ -5,7 +5,10 @@ import 'dart:math';
55/// Call the constructor before a loop starts, and call [wait]  in each iteration 
66/// of the loop.  Do not re-use the instance after exiting the loop. 
77class  BackoffMachine  {
8-   BackoffMachine ();
8+   BackoffMachine ({
9+     this .firstBound =  const  Duration (milliseconds:  100 ),
10+     this .maxBound =  const  Duration (seconds:  10 ),
11+   }) :  assert (firstBound <=  maxBound);
912
1013  /// How many waits have completed so far. 
1114  /// 
@@ -17,12 +20,12 @@ class BackoffMachine {
1720  /// The bound on the duration of the first wait. 
1821  /// 
1922  /// The actual duration will vary randomly up to this value; see [wait] . 
20- static   const  firstBound  =   Duration (milliseconds :   100 ) ;
23+ final   Duration  firstBound ;
2124
2225  /// The maximum bound on the duration of each wait, even after many waits. 
2326  /// 
2427  /// The actual durations will vary randomly up to this value; see [wait] . 
25- static   const  maxBound  =   Duration (seconds :   10 ) ;
28+ final   Duration  maxBound ;
2629
2730  /// The factor the bound is multiplied by at each wait, 
2831  /// until it reaches [maxBound] . 
@@ -35,17 +38,20 @@ class BackoffMachine {
3538  /// A future that resolves after an appropriate backoff time, 
3639  /// with jitter applied to capped exponential growth. 
3740  /// 
38-   /// A popular exponential backoff strategy is to increase the  duration 
39-   /// exponentially with the number of sleeps completed, with a base of 2,  
40-   /// until  a ceiling is reached.  E.g., if the first duration is 100ms and  
41-   /// the ceiling is 10s = 10000ms, the  sequence would be , in ms : 
41+   /// Each  [wait]  computes an upper bound on its wait  duration,  
42+   /// in a sequence growing exponentially from  [firstBound]  
43+   /// to  a cap of  [maxBound]  by factors of  [base] .  
44+   /// With their default values, this  sequence is , in seconds : 
4245  /// 
43-   ///   100, 200, 400, 800, 1600, 3200, 6400, 10000, 10000, 10000 , ... 
46+   ///   0.1, 0.2, 0.4, 0.8, 1.6, 3.2, 6.4, 10, 10, 10 , ... 
4447  /// 
45-   /// Instead of using this strategy directly, we also apply "jitter". 
46-   /// We use capped exponential backoff for the *upper bound* on a random 
47-   /// duration, where the lower bound is always zero.  Mitigating "bursts" is 
48-   /// the goal of any "jitter" strategy, and the larger the range of randomness, 
48+   /// To provide jitter, the actual wait duration is chosen randomly 
49+   /// on the whole interval from zero up to the computed upper bound. 
50+   /// 
51+   /// This jitter strategy with a lower bound of zero is reported to be more 
52+   /// effective than some widespread strategies that use narrower intervals. 
53+   /// The purpose of jitter is to mitigate "bursts" where many clients make 
54+   /// requests in a short period; the larger the range of randomness, 
4955  /// the smoother the bursts.  Keeping the lower bound at zero 
5056  /// maximizes the range while preserving a capped exponential shape on 
5157  /// the expected value.  Greg discusses this in more detail at: 
0 commit comments