1

For example, let's say I have a WebFilter that writes some Context

public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
  return chain.filter(exchange)
    .contextWrite(Context.of("my-context", "foobar"));
}

Downstream, my controller does this

@GetMapping(path = "test")
public Mono<String> test() throws Exception {
  final Mono<ContextView> contextMono = Mono.deferContextual(Mono::just);
  return contextMono.flatMap(ctx -> Mono.just(ctx.get("my-context")));
}

The above all works fine.

What if I wanted to return a Single from the controller method? I tried using RxJava3Adapter.monoToSingle() but it breaks the reactor chain.

@GetMapping(path = "test")
public Single<String> test() throws Exception {
  final Mono<ContextView> contextMono = Mono.deferContextual(Mono::just);
  return RxJava3Adapter.monoToSingle(
    contextMono.flatMap(ctx -> Mono.just(ctx.get("my-context"))));
}

My guess is that since I'm not returning the Mono, nothing subscribes to this contextMono inside of the RxJava3Adapter. Is that the right explanation?

Is there any way to return a Single while having the Context be passed in?

Martin Tarjányi
  • 8,863
  • 2
  • 31
  • 49
kane
  • 5,465
  • 6
  • 44
  • 72
  • This [blog](https://bsideup.github.io/posts/daily_reactive/thread_locals/) seems like it could be key to solving such a problem – kane Apr 04 '21 at 00:27

1 Answers1

3

The subscription itself works fine. The problem is that Context is a Reactor specific feature which is not part of the Reactive Streams standard. So when you convert a Mono to Single, the Context is lost.

In the code you attached you should just simply omit the Rx part to make it work but I imagine that your real world use case might be more convoluted. A good approach can be to convert the Rx code to Reactor at the earliest possible place (e.g. when you call the third-party library which returns the Rx type) and use Reactor in the rest of the codebase including the controller return type.

Martin Tarjányi
  • 8,863
  • 2
  • 31
  • 49
  • Is there a way to "hand off" the Context to Rx? My team has a lot of existing code in Rx but we also decided to migrate to Spring Webflux at the same time so I'm trying to resole the difference. – kane Apr 02 '21 at 17:57
  • 2
    Not that I know of. I took a quick look at RxJava wiki but couldn't find anything similar. Also, this closed issue indicates the same: https://github.com/ReactiveX/RxJava/issues/6484 – Martin Tarjányi Apr 02 '21 at 18:50