我希望能够将scalaz流中的数据发送到外部程序,然后在将来的大约100ms内恢复该项目的结果。虽然我能够通过使用输入流Sink
压缩输出流Process
然后丢弃Sink
副作用来使用下面的代码执行此操作,但我觉得此解决方案可能是非常脆弱。
如果外部程序的某个输入项有错误,则一切都将不同步。我觉得最好的办法是将一些增量ID发送到外部程序中,它可以在将来回显,以便在发生错误时我们可以重新同步。
我遇到的主要问题是将数据与程序Process[Task, Unit]
的输出一起发送到外部程序Process[Task, String]
的结果。我觉得我应该使用wyn
中的某些东西,但不是很确定。
import java.io.PrintStream
import scalaz._
import scalaz.concurrent.Task
import scalaz.stream.Process._
import scalaz.stream._
object Main extends App {
/*
# echo.sh just prints to stdout what it gets on stdin
while read line; do
sleep 0.1
echo $line
done
*/
val p: java.lang.Process = Runtime.getRuntime.exec("/path/to/echo.sh")
val source: Process[Task, String] = Process.repeatEval(Task{
Thread.sleep(1000)
System.currentTimeMillis().toString
})
val linesR: stream.Process[Task, String] = stream.io.linesR(p.getInputStream)
val printLines: Sink[Task, String] = stream.io.printLines(new PrintStream(p.getOutputStream))
val in: Process[Task, Unit] = source to printLines
val zip: Process[Task, (Unit, String)] = in.zip(linesR)
val out: Process[Task, String] = zip.map(_._2) observe stream.io.stdOutLines
out.run.run
}
答案 0 :(得分:0)
深入研究更高级的类型。看起来Exchange
完全符合我的要求。
import java.io.PrintStream
import scalaz._
import scalaz.concurrent.Task
import scalaz.stream._
import scalaz.stream.io._
object Main extends App {
/*
# echo.sh just prints to stdout what it gets on stdin
while read line; do
sleep 0.1
echo $line
done
*/
val program: java.lang.Process = Runtime.getRuntime.exec("./echo.sh")
val source: Process[Task, String] = Process.repeatEval(Task{
Thread.sleep(100)
System.currentTimeMillis().toString
})
val read: stream.Process[Task, String] = linesR(program.getInputStream)
val write: Sink[Task, String] = printLines(new PrintStream(program.getOutputStream))
val exchange: Exchange[String, String] = Exchange(read, write)
println(exchange.run(source).take(10).runLog.run)
}