2
votes

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
2

2 Answers

1
votes

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.

0
votes

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"));
    }

}