Haskell bounded worker pool using QSem
Haskell
import Control.Concurrent (forkIO, newEmptyMVar, putMVar, takeMVar)
import Control.Concurrent.QSem (newQSem, signalQSem, waitQSem)
import Control.Exception (SomeException, try)
import Control.Monad (forM)
workerPool :: Int -> [IO a] -> IO [Either SomeException a]
workerPool workers jobs = do
sem <- newQSem (max 1 workers)
slots <- forM jobs $ \job -> do
slot <- newEmptyMVar
_ <- forkIO $ do
waitQSem sem
outcome <- try job
putMVar slot outcome
signalQSem sem
pure slot
mapM takeMVar slots