Dynamic number of asyncs

I think we should keep the use of link but dispense with the nested withAsyncs.

Instead of that, we should keep an explicit set of Async values in a mutable reference. The main thread can cancel the pending asyncs as needed.

Something like (haven’t actually tested it :sweat_smile:)

main :: IO ()
main = do
    ref <- newIORef $ Data.Set.empty @(Async ())
    let register theAsync = 
            modifyIORef' ref $ Data.Set.insert theAsync
        finallyDeregister theAsync = flip finally $
            modifyIORef' ref $ Data.Set.delete theAsync
        launch conn = fixIO $ \theAsync -> async $ finallyDeregister theAsync $ handle conn
        loop = do
            bracketOnError awaitConn releaseConn $ \conn -> do
                bracketOnError (launch conn) uninterruptibleCancel $ \theAsync -> do
                    link theAsync
                    register theAsync
            loop
        cleanup = do
            asyncs <- readIORef ref
            for_ asyncs uninterruptibleCancel
    loop `onException` cleanup
1 Like