module Control.Concurrent.Throttle (throttle) where
import Control.Concurrent
import Control.Concurrent.MSemN
import qualified Control.Concurrent.Thread as Thread
import Control.Exception
import Control.Monad
throttle :: Int
-> [IO a]
-> IO [a]
throttle tps tasks =
do sem <- new tps
let runTask task = liftM snd $ wait sem 1 >> Thread.forkIO task
timeResetWorker = forever $ threadDelay 1000000 >> signalF sem (\i -> (tpsi, ()))
runAllTasks = mapM runTask tasks
mapM Thread.result =<< sequence =<< bracket (forkIO timeResetWorker)
killThread
(const runAllTasks)