rateLimit :: RateLimit -> IO a -> IO a
rateLimit (RateLimit lock delay) action =
    mask $ \restore -> do
        prev <- takeMVar lock
        now <- getTime Monotonic
        threadDelay' (prev + delay - now) `onException` putMVar lock prev
        restore action `finally` (putMVar lock =<< getTime Monotonic)
rateLimit :: RateLimit -> IO a -> IO a
rateLimit (RateLimit lock delay) action =
    mask $ \restore -> do
        prev <- takeMVar lock
        now <- getTime Monotonic
        threadDelay' (prev + delay - now) `onException` putMVar lock prev
        restore action `finally` (putMVar lock =<< getTime Monotonic)
rateLimit (RateLimit lock delay) action =
    mask $ \restore -> do
        prev <- takeMVar lock
        now <- getTime Monotonic
        threadDelay' (prev + delay - now) `onException` putMVar lock prev
        restore action `finally` (putMVar lock =<< getTime Monotonic)