{-# LANGUAGE DeriveGeneric #-}
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)