module NationStates.RateLimit (
RateLimit(),
newRateLimit,
rateLimit,
) where
import Control.Concurrent
import Control.Exception
import System.Clock
data RateLimit = RateLimit {
rateLock :: !(MVar TimeSpec),
rateDelay :: !TimeSpec
}
newRateLimit :: TimeSpec -> IO RateLimit
newRateLimit delay = do
lock <- newMVar $! negate delay
return RateLimit {
rateLock = lock,
rateDelay = delay
}
rateLimit :: RateLimit -> IO a -> IO a
rateLimit RateLimit { rateLock = lock, rateDelay = delay } action =
mask $ \restore -> do
prev <- takeMVar lock
now <- getTime Monotonic
threadDelay' $ prev + delay now
result <- restore action
putMVar lock =<< getTime Monotonic
return result
threadDelay' :: TimeSpec -> IO ()
threadDelay' t = threadDelay . fromInteger $ timeSpecAsNanoSecs t `div` 1000