在我的计划中,我正在启动外部流程,并通过stdin
和stdout
与其进行通信。我通过管道(生产者)从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
在我的程序中生成输出。
我是否遗漏了版本之间发生变化的内容?
答案 0 :(得分:1)
所以问题是sinkHandle
的默认行为changed在每个数据块之后都没有刷新。
我已经解决了这个问题,首先移植到Data.Conduit.Process.Typed
,然后滚动我使用sinkHandleFlush代替createSink
的{{1}}变体。