Yesterday I had a problem that core.async
provides an incredibly neat
solution to. Tim Baldridge was kind enough to sanity check it for me,
so I thought I'd write it up.
Imagine you want to process a message at a maximum rate of one per second. In another language you'd probably say something like:
while true:
start_time = date()
process_message(queue)
end_time = date()
elapsed_time = end_time.subtract(start_time)
if elapsed_time < 1000
sleep(1000 - elapsed_time)
Not hard to write, of course, but kinda clumsy. Here's the core.async
version:
(while true
(let [t (timeout 1000)]
(process-message queue)
(<!! t)))
In English, pick up a ticket that lasts for 1000 milliseconds; process a message; wait until the ticket expires. If processing the message took more than 1000ms, the ticket returns immediately, otherwise it blocks for the remaining time.
Simple and easy. A really neat solution.