Throttler: a Clojure library for rate limiting
brunov.org
brunov.org
We have a TCP connection down which we need to send (soft) real-time updates about a large data set. However, the thread sending out the updates has a fixed sized buffer per client that's shared between every part of the system communicating with that particular client. If the buffer gets full, it disconnects the client (incorrectly reasoning the fault was the client was requesting too much data).
In certain, not particularly uncommon circumstances, it was possible to end up needing to send out a large number of updates which would blow the buffer and disconnect the client. We considered various fixes that would give feedback about the size of the buffer, but the only feedback that would reliably not blow the buffer would be the block the producer when the buffer got full. This obviously has a huge rippling effect throughout the rest of the system, some of which have firmer real-time requirements, and was too big a task to fix at that time.
Looking at the updates, we observed there were two types of data patterns: frequent short bursts and these (comparatively) rare long sequence of updates. By rate limiting them to a maximum of n messages in any given window of a second the frequent short bursts would get sent immediately and unimpeded, while the long sequences would be broken up, giving the previous messages time to be dequeued from the buffer and sent down the TCP connection before the next batch arrived.
It's crude, but so far it's worked and given us time to work out a better system-wide solution to the problem.
In Ruby, ratelimit (https://github.com/ejfinneran/ratelimit) works nicely and the limit is shared across processes, which is very convenient.
I bet you could come up with other uses for it though. Someone told me over email they're planning on using it in traffic simulation for a game, for instance.
API Rate limiters should share global state using redis or something.
So perhaps, this is more for throttling functions
If it doesn't, let me know on Github and I'll look into it! I don't have any experience with CLJS, but I'm interested in learning so it'd be a good excuse.
ETA: Just realized that <!! and >!! aren't available in ClojureScript, so it needs some more work to be complete, but the pull request should help you get set up to develop for both.