我对如何使用MergeHub
感到困惑。
我正在设计一个使用Flow.mapAsync()
的流程图,其中给定的函数创建另一个流程图,然后使用Sink.ignore()
运行它,并返回CompletionStage
作为Flow.mapAsync()
要等待的值。嵌套流将通过实现Sink
返回的MergeHub
返回元素。
问题在于,当我创建顶级流程图时,我需要提供Function
来启动嵌套流程到Flow.mapAsync()
,但这需要它可以访问从实现MergeHub.of()
的结果返回的具体化值。如何在启动流程图之前获得该物化值?
我现在能看到的唯一方法是实现Function
阻止,直到提供Sink
(在启动顶级流程图之后),但这看起来很糟糕。< / p>
所以,像
class MapAsyncFunctor implements Function<T, CompletionStage<Done>> {...}
MapAsyncFunctor mapAsyncFunctor = new MapAsyncFunctor();
RunnableGraph<Sink<T>> graph = createGraph(mapAsyncFunctor);
Sink<T> sink = materializer.materialize(graph);
mapAsyncFunctor.setSink(sink); // Graph execution blocked in background in call to mapAsyncFunctor.apply() until this is done
编辑:我已创建以下课程
public final class Channel<T>
{
private final Sink<T, NotUsed> m_channelIn;
private final Source<T, NotUsed> m_channelOut;
private final UniqueKillSwitch m_killSwitch;
public Channel(Class<T> in_class, Materializer in_materializer)
{
final Source<T, Sink<T, NotUsed>> source = MergeHub.of(in_class);
final Sink<T, Source<T, NotUsed>> sink = BroadcastHub.of(in_class);
final Pair<Pair<Sink<T, NotUsed>, UniqueKillSwitch>, Source<T, NotUsed>> matVals = in_materializer.materialize(source.viaMat(KillSwitches.single(), Keep.both()).toMat(sink, Keep.both()));
m_channelIn = matVals.first().first();
m_channelOut = matVals.second();
m_killSwitch = matVals.first().second();
}
public Sink<T, NotUsed> in()
{
return m_channelIn;
}
public Source<T, NotUsed> out()
{
return m_channelOut;
}
public void close()
{
m_killSwitch.shutdown();
}
}
这样我就可以使用Source / Sink对来构建图形。这是一个好主意吗?我是否会泄漏&#39;这些渠道如果我没有明确关闭() 它们?
我只需要为我的用例使用.out()一次。
答案 0 :(得分:1)
使用MergeHub
始终需要在执行任何其他操作之前实现集线器接收器。
Sink<T, NotUsed> toConsumer = MergeHub.of(String.class, 16).to(consumer).run(materializer);
然后,您可以将其分发到需要实现它以向其发送数据的所有代码位。按照上面的代码段,可能的方法可能是在构建时通过Sink
您的仿函数:
class MapAsyncFunctor implements Function<T, CompletionStage<Done>> {
private Sink<T, NotUsed> sink;
public MapAsyncFunctor(Sink<T, NotUsed> sink) {
this.sink = sink;
}
@Override
public CompletionStage<Done> apply(T t) { /* run substream into sink */ }
}
MapAsyncFunctor mapAsyncFunctor = new MapAsyncFunctor(toConsumer);
// run your flow with mapAsync on the above functor
MergeHub
的更多信息可以在docs找到。