{-# LANGUAGE DeriveGeneric #-} -- | -- A utility module which lets you put a concurrency limit to an IO action. module Control.Concurrent.Throttled ( Throttle , newThrottle , throttled ) where -------------------------------------------------------------------------------- import Control.Monad (when) import Control.Exception (finally) import Control.Concurrent.STM -------------------------------------------------------------------------------- newtype Throttle = Throttle (TVar Int) newThrottle :: Int -> IO Throttle newThrottle lim = Throttle <$> newTVarIO (max lim 1) throttled :: Throttle -> IO a -> IO a throttled (Throttle tv) act = do atomically $ do r <- readTVar tv when (r == 0) retry writeTVar tv (r - 1) finally act $ atomically $ modifyTVar tv (+ 1)