我正在使用Java和Akka actor,但是需要调用类似于以下内容的旧Java API:
void legacyCall(OutputStream stdout, InputStream stdin, int timeout)
调用此API会阻塞,直到收到正确的输入,或者在达到超时时抛出异常。
我想要做的是每隔两秒向stdin发送一个换行符,直到我从stdout观察到某个输出。在普通的Java中,这可以通过几个线程和PipedInputStream
/ PipedOutputStream
完成,但由于我的应用程序使用的是Akka actor,我想让Akka管理这个任务而不是创建一个巨大的阻塞actor
所以我正在尝试使用Akka流来实现这一目标。到目前为止,我的理解是我至少需要两个来源,一个用于读取标准输出,另一个包含我的换行符,我将至少有一个接收器是stdin。
我拼凑了以下(非工作)代码:
Source<ByteString, OutputStream> stdout = StreamConverters.asOutputStream();
Sink<ByteString, InputStream> stdin = StreamConverters.asInputStream();
stdout
.toMat(stdin, Keep.right())
.mapMaterializedValue(is ->
try {
// how to materialize os (OutputStream) here as well?
legacyCall(os, is, timeoutSeconds);
} catch (TimeoutException e) {
// how to handle this
}
);
Source<String, NotUsed> newlines = Source.repeat("\n")
.throttle(1, Duration.create(2, TimeUnit.SECONDS), 1, ThrottleMode.shaping());
我认为至少有一些我缺少的东西:
OutputStream
和InputStream
流,以便我可以在一个位置访问这些流以传入legacyCall
?似乎API只支持一次实现一个值。Source
个新行?我不确定这些问题是否是正确的问题。任何建议都表示赞赏。