@@ -219,28 +219,28 @@ runAgainstBucket ::
219219  (Handlers  m  ->  m  a ) -> 
220220  m  (State  m , a )
221221runAgainstBucket config action =  do 
222-   runThreadVar  <-  atomically newEmptyTMVar --  see note [Leaky bucket design].
222+   leakingPeriodVersionTMVar  <-  atomically newEmptyTMVar --  see note [Leaky bucket design].
223223  tid <-  myThreadId
224224  bucket <-  init  config
225-   withAsync (leak runThreadVar  tid bucket) $  \ _ ->  do 
226-     atomicallyWithMonotonicTime $  maybeStartThread Nothing  runThreadVar  bucket
225+   withAsync (leak (readTMVar leakingPeriodVersionTMVar)  tid bucket) $  \ _ ->  do 
226+     atomicallyWithMonotonicTime $  maybeStartThread Nothing  leakingPeriodVersionTMVar  bucket
227227    result <- 
228228      action $ 
229229        Handlers 
230230          { fill =  \ r t ->  (snd  <$> ) $  snapshotFill bucket r t,
231231            setPaused =  setPaused bucket,
232-             updateConfig =  updateConfig runThreadVar  bucket
232+             updateConfig =  updateConfig leakingPeriodVersionTMVar  bucket
233233          }
234234    state <-  atomicallyWithMonotonicTime $  snapshot bucket
235235    pure  (state, result)
236236  where 
237-     --  Start the thread (that is, write to its 'runThreadVar ') if it is useful.
238-     --  Takes a potential old value of the 'runThreadVar ' as first argument,
237+     --  Start the thread (that is, write to its 'leakingPeriodVersionTMVar ') if it is useful.
238+     --  Takes a potential old value of the 'leakingPeriodVersionTMVar ' as first argument,
239239    --  which will be increased to help differentiate between restarts.
240240    maybeStartThread  ::  Maybe Int ->  StrictTMVar  m  Int ->  Bucket  m  ->  Time  ->  STM  m  () 
241-     maybeStartThread oldRunThread runThreadVar  bucket time =  do 
241+     maybeStartThread mLeakingPeriodVersion leakingPeriodVersionTMVar  bucket time =  do 
242242      State  {config =  Config  {rate}} <-  snapshot bucket time
243-       when (rate >  0 ) $  void $  tryPutTMVar runThreadVar  $  maybe  0  (+  1 ) oldRunThread 
243+       when (rate >  0 ) $  void $  tryPutTMVar leakingPeriodVersionTMVar  $  maybe  0  (+  1 ) mLeakingPeriodVersion 
244244
245245    setPaused  ::  Bucket  m  ->  Bool ->  Time  ->  STM  m  () 
246246    setPaused bucket paused time =  do 
@@ -253,7 +253,7 @@ runAgainstBucket config action = do
253253      ((Rational Config  m ) ->  (Rational Config  m )) -> 
254254      Time  -> 
255255      STM  m  () 
256-     updateConfig runThreadVar  bucket f time =  do 
256+     updateConfig leakingPeriodVersionTMVar  bucket f time =  do 
257257      State 
258258        { level =  oldLevel,
259259          paused,
@@ -272,9 +272,9 @@ runAgainstBucket config action = do
272272            configGeneration =  oldConfigGeneration +  1 ,
273273            config =  newConfig
274274          }
275-       --  Ensure that 'runThreadVar ' is empty, then maybe start the thread.
276-       oldRunThread  <-  tryTakeTMVar runThreadVar 
277-       maybeStartThread oldRunThread runThreadVar  bucket time
275+       --  Ensure that 'leakingPeriodVersionTMVar ' is empty, then maybe start the thread.
276+       mLeakingPeriodVersion  <-  tryTakeTMVar leakingPeriodVersionTMVar 
277+       maybeStartThread mLeakingPeriodVersion leakingPeriodVersionTMVar  bucket time
278278
279279--  |  Initialise a bucket given a configuration. The bucket starts full at the 
280280--  time where one calls 'init'. 
@@ -299,7 +299,7 @@ init config@Config {capacity} = do
299299--  ~~~~~~~~~~~~~~~~~~~~~~~~~~
300300-- 
301301--  The leaky bucket works by running the given action against a thread that
302- --  makes the bucket leak. Since that  would be extremely  inefficient to actually
302+ --  makes the bucket leak. Since it  would be inefficient to actually
303303--  remove tokens one by one from the bucket, the 'leak' thread instead looks at
304304--  the current state of the bucket, computes how much time it would take for the
305305--  bucket to empty, and then wait that amount of time. Once the wait is over, it
@@ -317,41 +317,42 @@ init config@Config {capacity} = do
317317--  for the action to lower the waiting time by changing the bucket configuration
318318--  to one where the rate is higher.
319319-- 
320- --  We fix both those issues with one mechanism, the @runThreadVar@. It is an 
321- --  MVar containing  an integer that tells the thread whether it should be 
322- --  running. An empty MVar means  that the thread should not be running, for 
323- --  instance if the rate is null. A full MVar ( no matter what the integer is) 
324- --  means that the  thread should be running. When recursing, the thread blocks 
325- --  until the MVar is full , and only then proceeds as described above.
320+ --  We fix both those issues with one mechanism, the @leakingPeriodVersionSTM@. 
321+ --  It is a computation returning  an integer that identifies a version of the 
322+ --  configuration  that controls  the leaking period. If the computation blocks, 
323+ --  it means that  no configuration has been determined yet. 
324+ --  The leak  thread first waits until @leakingPeriodVersionSTM@ yields a 
325+ --  value , and only then proceeds as described above.
326326--  Additionally, while waiting for the bucket to empty, the thread monitors
327- --  changes to the MVar, indicating either that the thread should stop running or
328- --  that the configuration changed as that it might have to wait less long. The
329- --  change in configuration is detected by changes in the integer.
327+ --  for changes to the version of the leaking period, indicating either that the
328+ --  thread should pause running if the @leakingPeriodVersionSTM@ starts blocking
329+ --  again or that the configuration changed as that it might have to wait less
330+ --  long.
330331-- 
331- --  Note that we call \“start\”/\“stop\” running the action of filling/emptying the
332- --  MVar. This is not to mistaken for the thread actually being spawned/killed.
333332
334- --  |  Monadic action  that calls 'threadDelay' until  the bucket is empty, then  
335- --  runs the 'onEmpty' action and terminates . See note [Leaky bucket design]. 
333+ --  |  Neverending computation  that runs 'onEmpty' whenever  the bucket becomes  
334+ --  empty . See note [Leaky bucket design]. 
336335leak  :: 
337336  ( MonadDelay  m ,
338337    MonadCatch  m ,
339338    MonadFork  m ,
340339    MonadAsync  m ,
341340    MonadTimer  m 
342341  ) => 
343-   --  |  A variable indicating whether the thread should run (when it is filled) 
344-   --  or not (otherwise). The integer it carries only helps in differentiating
345-   --  between starts and restarts. 'leak' does not modify this variable.
346-   StrictTMVar  m  Int -> 
342+   --  |  A computation indicating the version of the configuration affecting the 
343+   --  leaking period. Whenever the configuration changes, the returned integer
344+   --  must be incremented. While no configuration is available, the computation
345+   --  should block. Blocking is allowed at any time, and it will cause the
346+   --  leaking to pause.
347+   STM  m  Int -> 
347348  --  |  The 'ThreadId' of the action's thread, which is used to throw exceptions 
348349  --  at it.
349350  ThreadId  m  -> 
350351  Bucket  m  -> 
351352  m  () 
352- leak runThreadVar  actionThreadId bucket =  forever $  do 
353-       --  Block until we are allowed to run. Do not modify the TMVar. 
354-       oldRunThread  <-  atomically $  readTMVar runThreadVar 
353+ leak leakingPeriodVersionSTM  actionThreadId bucket =  forever $  do 
354+       --  Block until we are allowed to run.
355+       leakingPeriodVersion  <-  atomically leakingPeriodVersionSTM 
355356      --  NOTE: It is tempting to group this @atomically@ and
356357      --  @atomicallyWithMonotonicTime@ into one; however, because the former is
357358      --  blocking, the latter could get a _very_ inaccurate time, which we
@@ -377,7 +378,7 @@ leak runThreadVar actionThreadId bucket = forever $ do
377378            atomically $ 
378379              (check =<<  TVar. readTVar varTimeout)
379380                `orElse` 
380-               (void $  blockUntilChanged id  ( Just  oldRunThread)  $  tryReadTMVar runThreadVar )
381+               (void $  blockUntilChanged id  leakingPeriodVersion leakingPeriodVersionSTM )
381382
382383--  |  Take a snapshot of the bucket, that is compute its state at the current 
383384--  time. 
0 commit comments