-
Notifications
You must be signed in to change notification settings - Fork 70
Change semantics of withAsync & double performance of race and concurrently #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…rently Previously in "withAsync action inner" when "inner" would receive an asynchronous exception "action" would be killed. Now "action" will receive the same asynchronous exception has "inner". It's still the case that when"inner" receives a synchronous exception "action" will be killed. This change in semantics allows for an implementation of "race" and "concurrently" which is twice as fast because we can now fork a single thread instead of two. This patch was co-written with my colleague @asayers.
|
I'm beginning to suspect it's impossible to implement a concurrently left right =
withAsync left $ \a ->
withAsync right $ \b ->
waitBoth a bbut forks only a single thread. The following test case fails for my current implementation but succeeds for the spec: concurrently_3 :: Assertion
concurrently_3 = do
rightTidMv <- newEmptyMVar
exMv <- newEmptyMVar
forkIO $ do
threadDelay 1000
rightTid <- takeMVar rightTidMv
throwTo rightTid UserInterrupt
catchIgnore $
concurrently (threadDelay 100000 `catch` putMVar exMv)
(do rightTid <- myThreadId
putMVar rightTidMv rightTid
threadDelay 10000)
ex <- takeMVar exMv
ex @?= UserInterrupt
catchIgnore :: IO a -> IO ()
catchIgnore m = void m `catch` \(e :: SomeException) -> return ()I will give it another try tomorrow but I suspect I won't succeed :-( |
The latest commit actually passes the troublesome test-case. |
|
This is a really old PR. Can it be merged? |
|
@3noch perhaps.. I need to give it some serious thought. Is it important for you? |
|
@simonmar I'm not sure. I had a thread that was eating exceptions and took me hours to debug. I haven't tried this patch but it got me thinking. |
|
Probably not going to pursue this one. AFAIK the performance of |
Hi Simon,
This is an attempt to solve #5 by following your suggested approach of changing the semantics of
withAsyncsuch that if the inner function receives an asynchronous exception it will also be thrown to the forked action. But if it receives a synchronous action the forked action will be killed.This change in semantics allows for an implementation of
raceandconcurrentlywhich only needs to fork a single thread (instead of two) which doubles performance.I'm pretty sure that
concurrentlyis correct. I'm less sure aboutracebecause it uses a complex implementation. Although the test cases I added forraceseem to indicate it operates correctly.Let me know what you think.
This patch was co-written with my colleague @asayers.