Async job queues? [solved: use pooledMapConcurrently]

Does it? I have always thought the use case for the pooled*Concurrently family of functions was this exact scenario. In fact, I have modified the code @MangoIV provided to include the pooledMapConcurrently variant, and they seem to behave identical (wrt to the scheduling behavior). The output order seems to differ, but you mentioned that it is not important here:

{-# LANGUAGE BlockArguments #-}

module Main where

import UnliftIO
import UnliftIO.Concurrent
import System.Environment (getArgs)
import Data.Functor (($>))

work :: [IO a] -> IO [a]
work jobs = do
  sem <- newQSem =<< getNumCapabilities 
  go sem [] jobs
 where
  go _ acc [] = traverse wait acc
  go sem acc (job : jobs) = do
    as <- do
      waitQSem sem
      async do
        job `finally` signalQSem sem

    go sem (as : acc) jobs

work2 :: [IO a] -> IO [a]
work2 = pooledMapConcurrently id

main :: IO ()
main = do
  [variant] <- getArgs
  setNumCapabilities 2
  print =<< getNumCapabilities 
  worker <-
    if variant == "1"
       then putStrLn "handrolled variant" $> work
       else putStrLn "pooledMapConcurrently variant" $> work2
  print =<< worker (threads [n ^ 2 | n <- [10, 5, 1]])
 where
  threads = map \n -> do
    tid <- myThreadId
    let m = n * 100_000
    putStrLn (show tid <> ": sleeping " <> show m)
    threadDelay m
    putStrLn (show tid <> ": waking up")
    pure n

and the outputs:

$ cabal exec tmp-map-concurrently 1
2
handrolled variant
ThreadId 8: sleeping 2500000
ThreadId 7: sleeping 10000000
ThreadId 8: waking up
ThreadId 9: sleeping 100000
ThreadId 9: waking up
ThreadId 7: waking up
[1,25,100]

$ cabal exec tmp-map-concurrently 2
2
pooledMapConcurrently variant
ThreadId 8: sleeping 2500000
ThreadId 7: sleeping 10000000
ThreadId 8: waking up
ThreadId 8: sleeping 100000
ThreadId 8: waking up
ThreadId 7: waking up
[100,25,1]