An Elegant Little core.async Solution
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.