【发布时间】:2020-01-04 16:24:30
【问题描述】:
我需要运行一个进程,在它运行时做一些事情,最后终止它。这
有问题的进程将我想保留的内容写入标准输出。很遗憾,
似乎该过程在我连接并提取其遗言之前就死了。有稀缺
有异步编程经验,我很难找到一个好的解决方案。它
如果我能在RIO.Process 的框架内完成这项任务将是幸运的,尽管我
如果无法避免,我准备走出它。 (请注意,RIO 使用了一个不寻常的
通过回调系统调用外部进程的方式。)
下面是我试图实现的高度简化的可运行示例。
这是要运行的程序的模拟:
(将其放入名为 x.sh 的文件中并说 chmod +x x.sh 以使其可执行。)
#!/bin/sh
trap 'echo "Terminating..."; exit 0' TERM
echo "Initialization complete."
while true; do sleep 1; done
这是我的代码:
(将其放入名为 X.hs 的文件中并使用 ghc -package rio X.hs 进行编译。)
{-# language NoImplicitPrelude #-}
{-# language BlockArguments #-}
{-# language OverloadedStrings #-}
module Main where
import RIO
import RIO.Process
import Data.Text.IO (hGetContents, hGetLine)
main :: IO ()
main = runSimpleApp do
proc "./x.sh" [ ]
\processConfig -> withProcessWait_ (setStdout createPipe processConfig)
\processHandle -> bracket_
(initialize processHandle)
(terminate processHandle)
(return ())
initialize :: (HasProcessContext env, HasLogFunc env) => Process () Handle () -> RIO env ()
initialize processHandle = do
x <- liftIO $ hGetLine (getStdout processHandle)
if x == "Initialization complete." then return () else error "This should not happen."
terminate :: HasLogFunc env => Process () Handle () -> RIO env ()
terminate processHandle = do
log' <- async $ liftIO $ hGetContents (getStdout processHandle)
stopProcess processHandle
log <- wait log'
logInfo $ display log
会发生什么:
% ./X
X: fd:3: hGetBuffering: illegal operation (handle is closed)
——x.sh 正在说话,但我听不见。
管理这个问题的正确方法是什么?
【问题讨论】:
标签: haskell async-await rio