简体   繁体   English

Reactor fireAndForget Mono 传递上下文

[英]Reactor fireAndForget Mono pass context

I am trying to pass subscriber Context to the fireAndForget method which is called inside the doOnNext .我想用户通过ContextfireAndForget的方法被称为内部doOnNext The fireAndForget is run also async non-blocking. fireAndForget也是异步非阻塞运行的。 How this context might be passed so the value for "key" is present?如何传递此上下文以便“键”的值存在? When I run the following test it passes.当我运行以下测试时,它通过了。 However, in the logs I can see that for both doOnNext I get:但是,在日志中我可以看到对于doOnNext我得到:

reactor.core.Exceptions$ErrorCallbackNotImplemented: java.util.NoSuchElementException: Context is empty reactor.core.Exceptions$ErrorCallbackNotImplemented: java.util.NoSuchElementException: Context is empty

@Test
void shouldPassContextToFireAndForget() {
  final Mono<String> helloWorldMono = Mono.just("hello")
      .doOnNext(this::fireAndForget)
      .doOnNext(name -> Mono.deferContextual(contextView -> fireAndForget(contextView, name)).subscribe())
      .flatMap(name -> Mono.deferContextual(contextView -> Mono.just(name + " " + contextView.get("key"))))
      .contextWrite(Context.of("key", "world"));

  StepVerifier.create(helloWorldMono)
      .expectNext("hello world")
      .verifyComplete();
}

private Mono<String> fireAndForget(ContextView context, String name) {
  return Mono.just(name)
      .flatMap(value -> Mono.deferContextual(contextView -> Mono.just(value + contextView.get("key"))))
      .contextWrite(context);
}

private void fireAndForget(String name) {
  Mono.just(name)
      .flatMap(value -> Mono.deferContextual(contextView -> Mono.just(value + contextView.get("key"))))
      .subscribe();
}

Context is a subscribe-time concept. Context是一个订阅时间的概念。 There are two possible approaches.有两种可能的方法。

You can expose the ContextView at the middle of the chain using transformDeferredContextual :您可以使用transformDeferredContextual在链的中间公开ContextView

 final Mono<String> helloWorldMono = Mono.just("hello")
            .transformDeferredContextual((original, cntx) -> original.doOnNext(name-> fireAndForget(cntx, name).subscribe()))
            .flatMap(name -> Mono.deferContextual(contextView -> Mono.just(name + " " + contextView.get("key"))))
            .contextWrite(Context.of("key", "world"));

Alternatively, you could take advantage of Mono.deferContextual in order to expose the ContextView at the start of the chain like this:或者,您可以利用Mono.deferContextual在链的开头公开ContextView ,如下所示:

 final Mono<String> helloWorldMono = Mono.deferContextual(context ->
        Mono.just("hello")
            .doOnNext(name -> fireAndForget(context, name).subscribe())
            .flatMap(name -> Mono.just(name + " " + context.get("key")))
    ).contextWrite(Context.of("key", "world"));

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

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