简体   繁体   English

急停Akka流源

[英]Eagerly stop an Akka-Stream Source

I have the following (simplified) consumer that is supposed to cancel an Akka-Stream (2.11_2.5-SNAPSHOT of today) Source after the first item but the onNext is still getting called 4 times: 我有以下(简化)使用者,应该在第一个项目之后取消Akka-Stream(今天为2.11_2.5-SNAPSHOT) Source ,但onNext仍被调用4次:

static Subscriber<Object> println() {
    return new Subscriber<Object>() {

        Subscription s;

        int n;

        @Override
        public void onSubscribe(Subscription s) {
            this.s = s;
            s.request(5);
        }

        @Override
        public void onNext(Object t) {
            System.out.println(Thread.currentThread().getName() 
                  + ": " + t + " - " + (++n));
            if (s != null) {
                s.cancel();
                s = null;
            }
        }

        @Override
        public void onError(Throwable t) {
            t.printStackTrace();
        }

        @Override
        public void onComplete() {
            System.out.println(Thread.currentThread().getName() + ": DONE");
        }
    };
}

public static void main(String[] args) throws Exception {
    Config cfg = ConfigFactory.parseResources(
        AkkaRange.class, "/akka-streams.conf").resolve();
    ActorSystem actorSystem = ActorSystem.create("sys", cfg);

    ActorMaterializer materializer = ActorMaterializer.create(actorSystem);

    Source<Integer, NotUsed> source = Source.repeat(1);

    Publisher<Integer> p = source.runWith(Sink.asPublisher(
         AsPublisher.WITH_FANOUT), materializer);

    p.subscribe(println());

    Thread.sleep(1000);

    actorSystem.terminate();
}

Given that request is 5 yet only 4 calls are made, I assume the underlying messaging architecture responds to requests in 4-batches before checking the message queue for a cancellation (or further request) messages. 假设请求为5,但只进行了4次调用,我假设底层消息传递体系结构在检查消息队列中是否有取消消息​​(或其他请求)之前,先对4个批处理中的请求进行响应。

Is there a setting to make the cancellation happen more eagerly? 是否有设置可以使取消更紧急地进行?

The use case is something like an interop computation where there is a computationally intensive stage (map) that may produce a desired result after 1-2 source elements and the downstream cancels the stream in this case. 用例类似于互操作性计算,其中有一个计算密集型阶段(映射),在1-2个源元素之后可能会产生期望的结果,在这种情况下下游会取消该流。 The problem is that due to this 4 batch, the computation is executed for the remaining 2-3 elements too. 问题是由于这4个批次,对剩余的2-3个元素也执行了计算。

The Subscriber interface is a part of the Reactive Streams specification, which lots of libraries, akka-streams included, implement. Subscriber接口是Reactive Streams规范的一部分,该规范实现了许多库(包括akka流)。 And this specification states the following thing: 并且此规范声明了以下内容:

A Subscriber MUST be prepared to receive one or more onNext signals after having called Subscription.cancel() if there are still requested elements pending [see 3.12]. 如果仍有请求的元素待处理,则订阅者必须准备在调用Subscription.cancel()之后接收一个或多个onNext信号[参见3.12]。 Subscription.cancel() does not guarantee to perform the underlying cleaning operations immediately. Subscription.cancel()不保证立即执行基础清洁操作。

Therefore you have to handle this situation in your subscriber manually, otherwise it would be violating the specification and thus unfit to be used with the libraries implementing the spec. 因此,您必须在订户中手动处理这种情况,否则将违反规范,因此不适合与实现规范的库一起使用。

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

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