Skip to content
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

Deadlock when using $$& and the upstream uses throwError #47

Open
luispedro opened this issue Feb 7, 2017 · 1 comment
Open

Deadlock when using $$& and the upstream uses throwError #47

luispedro opened this issue Feb 7, 2017 · 1 comment

Comments

@luispedro
Copy link

When using $$& and the upstream conduit throws an exception with throwError, we get a deadlock.

I can trigger an error of the type Main.hs: thread blocked indefinitely in an STM transaction with the following code:

module Main
    ( main
    ) where


import qualified Data.Conduit.Combinators as C
import qualified Data.Conduit.List as CL
import           Data.Conduit ((=$=))
import           Data.Conduit.Async (($$&))
import           Control.Monad.Except
import           Control.Monad.Trans.Resource

data ErrorType = TriggerError deriving (Show, Eq)

main = runExceptT . runResourceT $
        (C.yieldMany [1 :: Int, 2, 3] >> throwError TriggerError)
                =$= CL.map (+1)
                $$& C.print
luispedro added a commit to ngless-toolkit/ngless that referenced this issue Feb 7, 2017
This is an upstream usage with ($$&), but badly formed files could crash
ngless with no error message, so refrain from using it. See:
cgaebel/stm-conduit#47
@qnikst
Copy link
Collaborator

qnikst commented Jul 30, 2023

I was not able to reproduce the problem as-is on the recent versions.

as-is the program does not compile with the error message

    • No instance for ‘MonadUnliftIO (ExceptT ErrorType IO)’
        arising from a use of ‘runResourceT’

So I've took the instance from the still opened discussion, and got the following program:

module Main
    ( main
    ) where


import qualified Data.Conduit.Combinators as C
import qualified Data.Conduit.List as CL
import           Data.Conduit ((=$=))
import           Data.Conduit.Async (($$&))
import           Control.Monad.Except
import           Control.Monad.Trans.Resource
import Control.Monad
import UnliftIO

data ErrorType = TriggerError deriving (Show, Eq)
instance Exception ErrorType

main = runExceptT . runResourceT $
        (C.yieldMany [1 :: Int, 2, 3] >> throwError TriggerError)
                =$= CL.map (+1)
                $$& C.print

instance (MonadUnliftIO m, Exception e) => MonadUnliftIO (ExceptT e m) where
  withRunInIO exceptToIO = ExceptT $ try $ do
    withRunInIO $ \runInIO ->
      exceptToIO (runInIO . (either throwIO pure <=< runExceptT))

When run it works as expected:

bash-3.2$ ./T
2
3
4
T: ExceptionInLinkedThread (ThreadId 2) TriggerError

So it's possible that the problems somewhere in instance for ExceptT. With the normal exceptions the same happening.

Should we close the ticket, or there is some other way or libraries set to reproduce the problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants