8
votes

Spring boot 2.1.5 Project Reactor 3.2.9

I am setting up a bunch of rest reactive APIs using the above-mentioned frameworks and I am running into an annoying problem with MDC (mapped diagnostic context). My applications are in JAVA.

MDC relies on thread locals to store the current query's mapped context to put in the logs. That system, obviously, is not perfect and contradicts the reactive pattern since the different steps of your execution will be executed through different threads.

I have run into the same problem with the Play Reactive framework but found a workaround there by copying the mapped context transparently from one actor to another.

For spring and reactor, I could not find a satisfying solution yet.

Some random examples found on the internet:

First - It works but forces you to use a bunch of utility methods

Same thing

Second - It tries to copy the context during the onNext publisher event but seems to lose some features on the way of doing that. The signal context, for example, is lost.

I am in need of a proper solution to deal with this:

  • A library which would make the link between MDC and reactor?
  • A way to tweak reactor/spring to achieve it transparently?
  • Any advice?
1
You should read this article simonbasle.github.io/2018/02/…Alexander Pankin
Yeah, it is the same thing as the first link I've put. You need a few of utility methods to access the context. And maybe that is all there is to it of course. I was hoping to be able to have something more transparent with less repetitive code.Arnaud Villevieille

1 Answers

6
votes

"I could not find a satisfying solution yet."

Working with contexts is the only solution for the moment. Since as you said threadlocals goes against everything that has to do with reactive programming. Using thread local as a storage point during a request is a resource heavy way of solving things and in my opinion poor design. Unless logging frameworks themselves come up with a better solution to the problem we developers must pass the data through the context to accommodate for the logging frameworks blocking nature.

Reactive programming is a paradigm shift in the programming world. Other things like database drivers, that use threadlocal to rollback transactions are also in big trouble. the JDBC database driver spec is defined as blocking in nature, and atm. there has been attempts by spring and the R2DBC project to define a new JDBC driver spec that is inherently non/blocking. This means that all vendors must rewrite ther database driver implementations from scratch.

Reactive program is so new that lots of libraries need to rewrite entire codebases. The logging frameworks as we know it needs to be rewritten from the ground up which is a huge task. And the context in reactive is actually something that should not even be in reactive programming, it was implemented just to accommodate for MDC problems.

It's actually a lot of overhead needing to pass data from thread to thread.

So what can we do?

  • push on logging frameworks, and/or help logging frameworks to rewrite their codebase
  • Accept that there is no "tweak" that will magically fix this
  • use the context and the way suggested in the blogposts

Project reactor context