This simple code results in a deadlock. Solution is to stick a yield inside the otherwise clause of the check function, but that's not always possible, since check can be pure function with a loop in it.
import Control.Concurrent.Async
someFunc :: IO ()
someFunc = do
w <- pooledCheck 2
if w == 2
then putStrLn "Success"
else putStrLn "Bug in implementation"
check :: Int -> Int -> IO Int
check step = go
where go n | even n = return n
| otherwise = go (n + step)
pooledCheck :: Int -> IO Int
pooledCheck step = do
let f = check step
either id id <$> race (f 1) (f 2)
Here is a repo that can be used to reproduce the issue: https://github.com/lehins/async-bug-repro running stack run should result in a deadlock
This simple code results in a deadlock. Solution is to stick a
yieldinside theotherwiseclause of thecheckfunction, but that's not always possible, since check can be pure function with a loop in it.Here is a repo that can be used to reproduce the issue: https://github.com/lehins/async-bug-repro running
stack runshould result in a deadlock