简体   繁体   中英

Spring Webflux Reactor context

In the following example, test2 should be able to access the context values from test and test1 , but it seems like that is not happening.

Any insight is welcome.

References:

  1. http://projectreactor.io/docs/core/release/reference/#context
  2. https://jira.spring.io/browse/SPR-15680
  3. https://simonbasle.github.io/2018/02/contextual-logging-with-reactor-context-and-mdc/ .

     import reactor.core.publisher.Mono; public class Test { public static void main(final String[] args) { System.out.println(Thread.currentThread().getName() + " main " + test()); } public static String test() { final String key = "message"; return test1().subscriberContext(ctx -> ctx.put(key, "test")).block(); } public static Mono<String> test1() { final String key = "message1"; return test2().subscriberContext(ctx -> ctx.put(key, "test1 ")); } public static Mono<String> test2() { return Mono.just("test2").map(item -> { Mono.subscriberContext().map(context -> { System.err.println(Thread.currentThread().getName() + " test2 " + context); return context; }); return item; }); }} 

Output:

main main test2

Seems like the following code works fine, but still not sure why the code in the question does not work.

import reactor.core.publisher.Mono;

public class Test {

    public static void main(final String[] args) {
        System.out.println(Thread.currentThread().getName()
            + " main "
            + test());
    }

    public static String test() {
        final String key = "message";
        return test1().subscriberContext(ctx -> ctx.put(key, "test")).block();
    }

    public static Mono<String> test1() {
        final String key = "message1";
        return test2().flatMap(item -> {
            Mono.subscriberContext().map(context -> {
                System.err.println(Thread.currentThread().getName()
                    + " test1 "
                    + context);
                return context;
            });
            return Mono.just(item);
        }).subscriberContext(ctx -> ctx.put(key, "test1 "));
    }

    public static Mono<String> test2() {
        final String key = "message2";
        return Mono.subscriberContext().flatMap(context -> {
            System.err.println(context);
            return Mono.just("test2");
        }).subscriberContext(ctx -> ctx.put(key, "test2"));
    }

}

I think, you wanted to access the subscriber context in the test2(), right? This only works, if you are actually in the same flow, so this snippet would fix the original code: Original:

public static Mono<String> test2() {
    return Mono.just("test2").map(item -> {
        // you're creating a new Mono context here, and don't return it/use it anymore
        Mono.subscriberContext().map(context -> {
            System.err.println(Thread.currentThread().getName()
                + " test2 "
                + context);
            return context;
        });
        return item;
    });

Fixed (with as few changes as possible, could be beautified):

public static Mono<String> test2() {
  return Mono.just("test2").flatMap(item -> { // changed map to flatmap, otherwise would be Mono<Mono<String>> here
    Mono<Context> contextMono = Mono.subscriberContext()
        .map(context -> {
          System.err.println(Thread.currentThread()
                                 .getName() + " test2 " + context);
          return context;
        });
    // let item be returned from "inside" of context Mono
    return contextMono.map(context -> item);
  });

I'm pretty much struggeling with the subscribercontext myself all the time - I find it not very clear, when the context was used as intended, and when not. I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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