简体   繁体   English

了解akka流中的背压Source.queue

[英]Understanding backpressure in akka streams Source.queue

I'm trying out akka streams, but i can't get backpressure to work in my simple example. 我正在尝试akka流,但我不能让背压在我的简单例子中工作。 I am admittely not experienced with akka (streams), so probably I'm missing something big. 我很幸运没有经历过akka(溪流),所以可能我错过了一些大事。

I am producing (offering on a queue) integers faster than consuming them, so I thought that backpressure would kick in. My goal is to always consume the most recent item that was put in the queue (that's why I have bufferSize = 1 and OverflowStrategy.dropHead() on the source queue). 我正在生产(提供队列)整数比消耗它们更快,所以我认为背压会起作用。我的目标是始终使用放入队列中的最新项目(这就是为什么我有bufferSize = 1和OverflowStrategy .dropHead()在源队列上)。

public class SimpleStream {
    public static void main(String[] argv) throws InterruptedException {
        final ActorSystem system = ActorSystem.create("akka-streams");
        final Materializer materializer = ActorMaterializer.create(system);

        final Procedure<Integer> slowConsumer = (i) -> {
            System.out.println("consuming [" + i + "]");
            ThreadUtils.sleepQuietly(1000, TimeUnit.MILLISECONDS);
        };

        final SourceQueue<Integer> q = Sink
                .<Integer>foreach(slowConsumer)
                .runWith(Source.<Integer>queue(1, OverflowStrategy.dropHead()),  materializer);

        final AtomicInteger i = new AtomicInteger(0);
        final Thread t = new Thread(() -> {
            while (!Thread.currentThread().isInterrupted()) {
                int n = i.incrementAndGet(); 
                q.offer(n);
                System.out.println("produced: [" + n + "]");
                ThreadUtils.sleepQuietly(500, TimeUnit.MILLISECONDS);
            }
        });
        t.setName("ticking");
        t.start();

        // run some time... to observe the effects.
        ThreadUtils.sleepQuietly(1, TimeUnit.HOURS);
        t.interrupt();
        t.join();

        // eventually shutdown akka here...
    }
}

However this is the result: 然而,这是结果:

produced: [1]
consuming [1]
produced: [2]
produced: [3]
consuming [2] <-- Expected to be consuming 3 here.
produced: [4]
produced: [5]
consuming [3] <-- Expected to be consuming 5 here.
produced: [6]
produced: [7]

Please ignore the threading stuff here and there just to fake getting data from an external source (like it would happen if I had to use this in a real project). 请忽略这里的线程内容,只是假冒从外部源获取数据(如果我必须在实际项目中使用它,就会发生这种情况)。

Any idea of what I'm missing? 知道我错过了什么吗?

Source.queue terminates the signalling of back pressure. Source.queue终止Source.queue的信号。 That is why the Source.queue method takes in an OverflowStrategy . 这就是Source.queue方法接受OverflowStrategy If back pressure could be signalled upstream past the queue then there would be no need to deal with a situation where the queue could potentially overflow. 如果可以在队列的上游发信号通知背压,那么就不需要处理队列可能溢出的情况。 But since back pressure does not propagate past the queue a strategy needs to be defined to deal with a producer that is faster than a consumer. 但由于背压不会传播通过队列,因此需要定义策略来处理比消费者更快的生产者。

With typical streams the ultimate Source receives demand from the Sink to produce more results. 通过典型的流,最终的Source接收来自Sink需求以产生更多结果。 However, with a stream created from Source.queue the "ultimate source" is a queue. 但是,使用从Source.queue创建的流,“最终源”是队列。 This queue can only drain the contents, if there is any. 如果有的话,这个队列只能排出内容。 It can't signal upstream to generate more results because the upstream is on the other side of the offer method. 它不能向上游发出信号以产生更多结果,因为上游位于offer方法的另一侧。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM