无法通过stdin将数据传递给使用conduit-extra生成的进程

时间:2018-02-11 11:40:42

标签: haskell haskell-stack stm conduit

在我的计划中,我正在启动外部流程,并通过stdinstdout与其进行通信。我通过管道(生产者)从STM s TQueue开始输入输入。在我决定碰撞lts版本之前,它就像一个魅力。它与lts< = 8.24。

一起工作得很好

这是重现我的问题的最小化程序:

#!/usr/bin/env stack
-- stack --resolver lts-10.4 --install-ghc runghc --package conduit-extra --package stm-conduit
{-# LANGUAGE OverloadedStrings #-}
import Control.Concurrent
import Control.Monad.STM
import Control.Concurrent.STM.TQueue

import           Data.Conduit
import qualified Data.Conduit.Binary       as CB
import qualified Data.Conduit.List         as CL
import           Data.Conduit.Process     (CreateProcess (..),
                                           proc, sourceProcessWithStreams)
import qualified Data.Conduit.TQueue       as CTQ

import qualified Data.ByteString.Char8     as BS
import           Data.Monoid              ((<>))

main :: IO ()
main = do
  putStrLn "Enter \"exit\" to exit."

  q <- open
  putStrLn "connection opened"

  loop q
  where loop q = do
          s <- BS.getLine
          case s of
            "exit" -> return ()
            req -> do
              atomically $ writeTQueue q req
              loop q

open :: IO (TQueue BS.ByteString)
open = do
  req <- atomically newTQueue
  let chat :: CreateProcess
      chat = proc "cat" []

      input :: Producer IO BS.ByteString
      input = toProducer
            $ CTQ.sourceTQueue req
           -- .| CL.mapM_ (\bs -> BS.putStrLn (("queue: " :: BS.ByteString) <> bs))

      output :: Consumer BS.ByteString IO ()
      output = toConsumer
             $ CL.mapM_ BS.putStrLn

  _ <- forkIO (sourceProcessWithStreams chat input output output >> pure ())
  pure req

对于较新的lts,似乎问题是通过TQueue进行通信,因为取消注释从输入管道打印内容的行会显示队列中的数据。看起来生成的进程永远不会收到stdin上的任何内容。

此外从控制台写入催生的猫stdin,如下:

echo "test" > /proc/<pid of spawned cat>/fd/0

在我的程序中生成输出。

我是否遗漏了版本之间发生变化的内容?

1 个答案:

答案 0 :(得分:1)

所以问题是sinkHandle的默认行为changed在每个数据块之后都没有刷新。

我已经解决了这个问题,首先移植到Data.Conduit.Process.Typed,然后滚动我使用sinkHandleFlush代替createSink的{​​{1}}变体。