-
Notifications
You must be signed in to change notification settings - Fork 196
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
Why was this done to MonadResource? #431
Comments
This is where they rely on MonadBaseControl. They're using it "for saving and restoring the state of monad when we fork a concurrent thread". Here's the code where they use it. Can they achieve their aims without using MonadBaseControl? ------------------------------------------------------------------------------
-- Spawning threads
------------------------------------------------------------------------------
-- | A monad that can perform concurrent or parallel IO operations. Streams
-- that can be composed concurrently require the underlying monad to be
-- 'MonadAsync'.
--
-- @since 0.1.0
type MonadAsync m = (MonadIO m, MonadBaseControl IO m, MonadThrow m)
-- When we run computations concurrently, we completely isolate the state of
-- the concurrent computations from the parent computation. The invariant is
-- that we should never be running two concurrent computations in the same
-- thread without using the runInIO function. Also, we should never be running
-- a concurrent computation in the parent thread, otherwise it may affect the
-- state of the parent which is against the defined semantics of concurrent
-- execution.
newtype RunInIO m = RunInIO { runInIO :: forall b. m b -> IO (StM m b) }
captureMonadState :: MonadBaseControl IO m => m (RunInIO m)
captureMonadState = control $ \run -> run (return $ RunInIO run)
-- Stolen from the async package. The perf improvement is modest, 2% on a
-- thread heavy benchmark (parallel composition using noop computations).
-- A version of forkIO that does not include the outer exception
-- handler: saves a bit of time when we will be installing our own
-- exception handler.
{-# INLINE rawForkIO #-}
rawForkIO :: IO () -> IO ThreadId
rawForkIO action = IO $ \ s ->
case fork# action s of (# s1, tid #) -> (# s1, ThreadId tid #)
{-# INLINE doFork #-}
doFork :: MonadBaseControl IO m
=> m ()
-> RunInIO m
-> (SomeException -> IO ())
-> m ThreadId
doFork action (RunInIO mrun) exHandler =
control $ \run ->
mask $ \restore -> do
tid <- rawForkIO $ catch (restore $ void $ mrun action)
exHandler
run (return tid) Code BSD3- licensed, taken from here: https://github.com/composewell/streamly/blob/v0.7.0/src/Streamly/Internal/Data/SVar.hs#L888 |
You shouldn't rely on https://www.fpcomplete.com/blog/2017/07/announcing-new-unliftio-library https://old.reddit.com/r/haskell/comments/6nr9ya/announcing_the_new_unliftio_library/ |
@bitemyapp Unfortunately, I'm not sure we can do without it. If we can, great. If not, we'd have proof that resourcet can no longer do things it previously could. I don't have enough expertise to establish which. |
Here is example of people talking. MonadResource did something useful for them, but since the unliftio change, MonadResource became useless. Why was a popular "standard" type class in the Haskell community damaged like this?
What can be done, if anything?
The text was updated successfully, but these errors were encountered: