Java Akka流丢弃消息?
我是阿克卡溪的新手。我在Java中使用它。(akka-stream_2.12,版本:2.5.14) 我写了以下课程:Java Akka流丢弃消息?,java,akka,akka-stream,Java,Akka,Akka Stream,我是阿克卡溪的新手。我在Java中使用它。(akka-stream_2.12,版本:2.5.14) 我写了以下课程: package main; import java.io.IOException; import akka.actor.ActorSystem; import akka.stream.ActorMaterializer; import akka.stream.Materializer; import akka.stream.OverflowStrategy; import a
package main;
import java.io.IOException;
import akka.actor.ActorSystem;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;
import akka.stream.OverflowStrategy;
import akka.stream.javadsl.Sink;
import akka.stream.javadsl.Source;
import akka.stream.javadsl.SourceQueueWithComplete;
public class AkkaTest {
public static void main(String[] args) throws IOException, InterruptedException {
final ActorSystem actorSystem = ActorSystem.create("VehicleSystem");
final Materializer materializer = ActorMaterializer.create(actorSystem);
SourceQueueWithComplete<Object> componentA_outPort1 =
Source.<Object>queue(100, OverflowStrategy.backpressure()).async()
.to(Sink.foreach(str -> System.out.println(str)))
.run(materializer);
for(int i=1; i<100000; i++)
componentA_outPort1.offer("Akka rocks: " + i);
System.in.read();
actorSystem.terminate();
System.out.println("Done.");
}
}
packagemain;
导入java.io.IOException;
导入akka.actor.actor系统;
进口akka.stream.actormatarializer;
导入akka.stream.Materializer;
导入akka.stream.OverflowStrategy;
导入akka.stream.javadsl.Sink;
导入akka.stream.javadsl.Source;
导入akka.stream.javadsl.SourceQueueWithComplete;
公共类AkkaTest{
公共静态void main(字符串[]args)引发IOException、InterruptedException{
最终ActorSystem ActorSystem=ActorSystem.create(“车辆系统”);
final-Materializer-Materializer=ActorMaterializer.create(actorSystem);
SourceQueueWithComplete组件A_outPort1=
queue(100,OverflowStrategy.backpressure()).async()
.to(Sink.foreach(str->System.out.println(str)))
.run(物化器);
对于(int i=1;i这里问题的第一个提示是“完成”并没有在末尾打印到控制台上。相反,它打印在开头或“Akka rocks”打印之间的某个地方
这是因为SourceQueue.offer
是异步的。它返回一个CompletionStage
,您不需要等待它的完成。一些流元素“丢失”的事实可以用以下部分来解释,具体如下:
此外,当使用背压溢出策略时:-如果缓冲区已满,则在缓冲区中有空间之前不会完成未来-在这种情况下,在未来完成之前调用要约将返回失败的未来
您可以通过执行以下操作来验证这一点:
SourceQueueWithComplete<Object> componentA_outPort1 =
Source.<Object>queue(100, OverflowStrategy.backpressure()).async()
.to(Sink.foreach(str -> System.out.println(str)))
.run(materializer);
for (int i=1; i<100000; i++) {
CompletionStage<QueueOfferResult> result = componentA_outPort1.offer("Akka rocks: " + i);
System.out.println(result);
}
对于更复杂的情况,考虑源的其他静态方法,如“代码>源代码”,从中获取迭代或“代码>源”。FruteReals< /C> >
两件事:
为源队列
提供信息的惯用方法是使用另一个源
(正如佩德罗在回答中提到的)
您可能在流完成处理之前终止actor系统
一旦接收器的物化值完成,请关闭系统:
import java.util.concurrent.CompletionStage;
import akka.Done;
import akka.japi.Pair;
import akka.stream.javadsl.Keep;
import akka.stream.javadsl.RunnableGraph;
// other imports...
Sink<String, CompletionStage<Done>> sink =
Sink.foreach(str -> System.out.println(str));
Source<String, SourceQueueWithComplete<String>> outPort =
Source.<String>queue(100, OverflowStrategy.backpressure()).async();
RunnableGraph<Pair<SourceQueueWithComplete<String>, CompletionStage<Done>>> stream =
outPort.toMat(sink, Keep.both());
Pair<SourceQueueWithComplete<String>, CompletionStage<Done>> pair = stream.run();
Source.range(1, 100000)
.map(i -> "Akka rocks: " + i)
.mapAsync(1, s -> pair.first().offer(s))
.runWith(Sink.ignore(), materializer);
pair.second().thenRun(() -> actorSystem.terminate());
import java.util.concurrent.CompletionStage;
进口阿克卡。完成;
进口akka.japi.Pair;
导入akka.stream.javadsl.Keep;
导入akka.stream.javadsl.RunnableGraph;
//其他进口。。。
水槽=
Sink.foreach(str->System.out.println(str));
源输出端口=
queue(100,OverflowStrategy.backpressure()).async();
RunnableGraph流=
toMat(sink,Keep.both());
Pair Pair=stream.run();
来源.范围(11000)
.地图(i->“阿克卡岩石:”+i)
.mapsync(1,s->pair.first().offer)
.runWith(Sink.ignore(),物化器);
然后运行(()->actorSystem.terminate());
寻求调试帮助的问题(“为什么此代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现问题所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:。我编辑了示例。现在更好了吗?我发布的示例是我试图实现的结果的简化版本。在实际代码中,我想将事件发送到流,而事件可能在不同的时间到达。因此,一个具有范围的简单源是不够的。我还肯定需要一个异步边界。使用.mapsync的解决方案与使用.async()的解决方案不同吗,关于异步处理?使用mapsync
和使用定义异步边界。async
是不同的。请阅读本文了解更多详细信息。您可能希望尝试调整并行级别(第一个参数为mapsync
)。
Source.range(1, 1000).map(i -> "Akka rocks: " + i)
import java.util.concurrent.CompletionStage;
import akka.Done;
import akka.japi.Pair;
import akka.stream.javadsl.Keep;
import akka.stream.javadsl.RunnableGraph;
// other imports...
Sink<String, CompletionStage<Done>> sink =
Sink.foreach(str -> System.out.println(str));
Source<String, SourceQueueWithComplete<String>> outPort =
Source.<String>queue(100, OverflowStrategy.backpressure()).async();
RunnableGraph<Pair<SourceQueueWithComplete<String>, CompletionStage<Done>>> stream =
outPort.toMat(sink, Keep.both());
Pair<SourceQueueWithComplete<String>, CompletionStage<Done>> pair = stream.run();
Source.range(1, 100000)
.map(i -> "Akka rocks: " + i)
.mapAsync(1, s -> pair.first().offer(s))
.runWith(Sink.ignore(), materializer);
pair.second().thenRun(() -> actorSystem.terminate());