quarkusio / quarkus

Quarkus: Supersonic Subatomic Java.
https://quarkus.io
Apache License 2.0
13.8k stars 2.68k forks source link

RESTEasy Reactive: Context propagation between prematching request filter and blocking endpoint #15826

Closed jsebtes closed 1 month ago

jsebtes commented 3 years ago

Describe the bug

Context propagation seem does not work properly between a request filter with @ServerRequestFilter(preMatching = true) and an endpoint with @Blocking. A value set in a context in the filter cannot be read in the endpoint. If preMatching is set to true, context propagation works well for non @Blocking endpoint. If preMatching is set to false, context propagation works well for @Blocking and for non @Blocking endpoint.

Expected behavior

Context propagation works also between a @ServerRequestFilter(preMatching = true) and a @Blocking endpoint.

Actual behavior

Context propagation does not works if preMatching = true and a @Blocking endpoint.

To Reproduce

https://github.com/jsebtes/context-propagation-reproducer

working endpoint : http://localhost:8080/hello-resteasy-reactive => Context propagation works well (non blocking endpoint)

failing endpoint : http://localhost:8080/hello-resteasy-reactive/blocking => Context propagation does not works (blocking endpoint)

Steps to reproduce the behavior:

  1. execute HTTP GET: http://localhost:8080/hello-resteasy-reactive
  2. execute HTTP GET: http://localhost:8080/hello-resteasy-reactive/blocking

Configuration

No configuration necessary

Screenshots

Environment (please complete the following information):

Output of uname -a or ver

Output of java -version

openjdk version "11.0.10" 2021-01-19 OpenJDK Runtime Environment AdoptOpenJDK (build 11.0.10+9) OpenJDK 64-Bit Server VM AdoptOpenJDK (build 11.0.10+9, mixed mode)

GraalVM version (if different from Java)

Quarkus version or git rev

1.12.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f) Maven home: C:\Users\Jean-Sébastien.m2\wrapper\dists\apache-maven-3.6.3-bin\1iopthnavndlasol9gbrbg6bf2\apache-maven-3.6.3 Java version: 11.0.10, vendor: AdoptOpenJDK, runtime: C:\Program Files\AdoptOpenJDK\jdk-11.0.10.9-hotspot Default locale: fr_FR, platform encoding: Cp1252 OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"

Additional context

quarkus-bot[bot] commented 3 years ago

/cc @FroMage, @geoand, @stuartwdouglas

geoand commented 3 years ago

@FroMage seems like we need to enable CP when offloading the task to the worker thread

FroMage commented 3 years ago

Yeah, I don't think we do anything CP-specific ATM.

geoand commented 3 years ago

Yup, we'll need to support that

jsebtes commented 3 years ago

I updated my test project to the last version of quarkus (2.2.3), and the problem still seems to exist. => https://github.com/jsebtes/context-propagation-reproducer/tree/quarkus2.2.3

I'm new to Quarkus, and I must admit that I didn't quite understand your initial answer :-) How can I help ?

jsebtes commented 2 years ago

Reproducer updated to quarkus 2.7.4 => https://github.com/jsebtes/context-propagation-reproducer/tree/quarkus2.7.4

geoand commented 1 month ago

Is this still an issue with the latest version of Quarkus?

jsebtes commented 1 month ago

Reproducer updated to quarkus 3.14 => https://github.com/jsebtes/context-propagation-reproducer/tree/quarkus3.14

The issue seems to be still present, the reproducer does not work.

geoand commented 1 month ago

🙏

geoand commented 1 month ago

I used the excellent reproducer and I understand where the confusion is coming from.

Quarkus REST / RESTEasy Reactive actually doesn't utilize Context Propagation between the various steps it has to handle a request. The reason why you see preMatching=false work for both blocking and non-blocking is because the Filter and Resource methods are actually being run on the same thread no matter whether reactive is used or not.

Might I ask what information you are trying to capture in the filter and where you are trying to access it later on?

jsebtes commented 1 month ago

Thanks for your response and for the explanation.

It's a old issue, so I don't remember exactly my use case, sorry. But I think I was trying to reproduce, with Quarkus, our custom tracing library. Basically, this library get an id from a request header, or generate one if empty. Put it in the MDC logging context (in order to have this value in all log entry) and in a "context" / a Thread variable (in order to be able to get and progagate this value to other services from anywhere in our business logic).

In our actual implementation, we get the tracing id header value / generate a new id value as soon as possible in the request processing, even before security processing, for having this tracing id in security log entry as well. So I think that's why I wanted to enable preMatching=true on my filter, to make it run as early as possible. And I have some upload file endpoints, so I think this is why I tested that with a blocking endpoint.

From what point is context propagation ensured by Quarkus REST ? From my Resource method ? Before in the request processing ?

geoand commented 1 month ago

Thanks a lot for the information!

I totally understand why you expect Context Propagation to work in the case you described, but the reason it doesn't is that Context Propagation is very expensive and if we were to enable it in Quarkus REST / RESTEasy Reactive, we would be putting a huge performance tax on everyone.

What you can do however for your use case is use Vert.x Context Locals that are very cheap and are available throughout the handling of the request. See this for more information.

jsebtes commented 1 month ago

Thanks a lot for your time and the advice

geoand commented 1 month ago

🙏🏽