module Network.IRC.Bot.Limiter
( Limiter(..)
, newLimiter
, limit
)
where
import Control.Concurrent (ThreadId, forkIO, threadDelay)
import Control.Concurrent.QSem (QSem, newQSem, signalQSem, waitQSem)
import Control.Monad (forever)
data Limiter = Limiter
{ limitsIn :: QSem
, limitsOut :: QSem
, limitsDelay :: Int
, limitsThreadId :: ThreadId
}
newLimiter :: Int
-> Int
-> IO Limiter
newLimiter burst delay = do
rdy <- newQSem burst
sent <- newQSem 0
let l = Limiter { limitsIn = sent
, limitsOut = rdy
, limitsDelay = delay
, limitsThreadId = error "limiter thread not started yet"
}
tid <- forkIO (limiter l)
return $ l { limitsThreadId = tid }
limit :: Limiter -> IO ()
limit l = do
waitQSem (limitsOut l)
signalQSem (limitsIn l)
limiter :: Limiter -> IO b
limiter l = forever $ do
waitQSem (limitsIn l)
threadDelay (limitsDelay l)
signalQSem (limitsOut l)