README added

parent 02f5ed9e
dist-newstyle/
\ No newline at end of file
.idea/
dist-newstyle/
docs/
\ No newline at end of file
# haskell-throttle
A [throttle](https://en.wikipedia.org/wiki/Rate_limiting)
implementation using
[`Control.Concurrent.STM.TChan`](https://hackage.haskell.org/package/stm-2.5.3.1/docs/Control-Concurrent-STM-TChan.html).
## Rationale
Current Haskell throttle implementations
(e.g. [`Data.Conduit.Throttle`](https://hackage.haskell.org/package/conduit-throttle-0.3.1.0/docs/Data-Conduit-Throttle.html)
or [`io-throttle](https://hackage.haskell.org/package/io-throttle))
work by just __slowing down__ incoming messages. However, sometimes we
don't care about delivering __all__ messages, but just want to limit
their rate. Hence this module is born.
The main function is in
[`Control.Concurrent.Throttle`](./src/Control/Concurrent/Throttle.hs):
```Haskell
throttle :: (Ord id, Eq id, Show id) => Int -> TChan.TChan (id, a) -> (a -> IO ()) -> IO ()
```
It takes as arguments:
- resolution (in milliseconds)
- a `TChan` where `(id, a)` tuples are sent
- `action` which, for given `a` calls some `IO` action
In the above we have 2 types:
- `a` represents the incoming message which will be called with the supplied `action`
- `id` represents some identifier associated with the message. By
using this `id` we can perform grouping of messages and throttle
them accordingly.
The `throttle` function itself should be spawned in a separate
thread. It then awaits for incoming messages on the given `TChan`.
See [`test` directory](./test) for a sample usage.
## Design
Currently, the `throttle` function spawns a `mapCleaner` thread which,
periodically, checks the internal `TVar` value for values to clean up
and values to hold before the given delay happens.
......@@ -76,7 +76,7 @@ throttle delay tchan action = do
-- * an item not in 'canRun' was added
atomically $
TVar.modifyTVar smap $
Map.filterWithKey (\k (_, t) -> (isNothing $ Map.lookup k canRun) || (now - t > 0 && now - t < delay))
Map.filterWithKey (\k (_, t) -> isNothing (Map.lookup k canRun) || (now - t > 0 && now - t < delay))
threadDelay (delay `div` 2)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment