Closed michalvavrik closed 10 months ago
/cc @Ladicek (arc), @alesj (grpc), @cescoffier (grpc), @geoand (kubernetes), @iocanel (kubernetes), @manovotn (arc), @mkouba (arc)
cc @sberyozkin related to #37472
Hello @cescoffier @mkouba @Ladicek @manovotn I had a look into this and I found out that CDI request scope is never activated which is for some reason expected
I have updated this issue description with brand new reproducer and I propose to drop that line completely. I'll try to drop it, create test and see what Quarkus CI has to say, but I am pretty sure the PR will be rejected. Why is it implemented this way? I'd like to be able to terminate CDI request context even on duplicated context as well.
I debugged RESTEasy Classic and I think there is another underlying issue that makes things happen only because deactivation is not actually happening (due to this bug), I'll leave experts to deal with it. Please also check how many times request context in io.quarkus.arc.runtime.context.ArcContextProvider.NullContextSnapshot
is activated / deactivated when running mvn clean verify -f integration-tests/smallrye-jwt-token-propagation/ -Dtest-containers -Dstart-containers -Dtest=OidcTokenPropagationTest#testEchoUserNameWithAccessTokenPropagation -Dmaven.surefire.debug
and there are other examples (see CI of my closed PR). I can't tell if there is a good reason for such behavior, I'll leave it on you.
Adjusted labels because this is the Arc bug - Jakarta CDI 4.0 specification in 2.5.5.2. Activating Built In Contexts subsection Activating a Request Context says that @ActivateRequestContext
is supposed to deactive request context upon method completion, which is not happening.
Adjusted labels because this is the Arc bug - Jakarta CDI 4.0 specification in 2.5.5.2. Activating Built In Contexts subsection Activating a Request Context says that
@ActivateRequestContext
is supposed to deactive request context upon method completion, which is not happening.
Keep in mind that the @ActivateRequestContext
interceptor only deactivates the request context if it was activated by this interceptor before the intercepted method was invoked. In other words, it does not deactivate the request context if it was already active.
I did not look into the details of this issue though. Does the method return an async type, e.g. Uni
? ArC has some special handling of for async types (which is not standardized by the way).
I appreciate you read my comment @mkouba , this is not urgent at all, but I was wondering if you know about it :-)
Keep in mind that the
@ActivateRequestContext
interceptor only deactivates the request context if it was activated by this interceptor before the intercepted method was invoked. In other words, it does not deactivate the request context if it was already active.
I used @ActivateRequestContext
interceptor as I could find it in spec, but I didn't see there Arc.container().requestContext().terminate()
, only found mention of deactivating request context. It happens with or without the interceptor, only requirement is to be on duplicated context, which is IMO common case when processing HTTP requests in Vert.x HTTP extension.
I re-tested it yesterday after https://github.com/quarkusio/quarkus/pull/37982 got merged and I still can reproduce it.
I did not look into the details of this issue though. Does the method return an async type, e.g.
Uni
? ArC has some special handling of for async types (which is not standardized by the way).
This also happens when something is returned in a synchronous way. io.quarkus.arc.impl.RequestContext#isActive
returns true
when current context state is not null, which is always true once the request scope has been activated, because it is not removed here io.quarkus.vertx.runtime.VertxCurrentContextFactory.VertxCurrentContext#remove
. Destroy works, deactivation does not.
That said, I tried to fix it and it is really complex in scenarios like RESTEasy Classic, there can be something I'm missing. I just think deactivation should work, otherwise it's misleading operation.
I have updated this issue description with brand new reproducer and I propose to drop that line completely. I'll try to drop it, create test and see what Quarkus CI has to say, but I am pretty sure the PR will be rejected. Why is it implemented this way? I'd like to be able to terminate CDI request context even on duplicated context as well.
I tried looking into history to see why we chose to never remove req. context state from the vertx duplicated context and the only link I found was this comment... which sadly doesn't tell me much.
But I agree it's awkward because you are then left with context that is active but its ContextState
is actually invalid
:thinking:
Maybe requestContext().isActive()
should also check for validity of the underlying ContextState
?
I'll keep digging a bit more...
When CDI event is fired asynchronously and the CDI request context is activated, it should not be detectable by
Arc.container.request().isActive()
Note that Arc.container().requestContext()
may return different context based on where you invoke that from. So from within an async observer of that event, you should see it active, but from the thread that fired the even, that depends on whether it was previously active or not. And both of these contexts will have different underlying ContextState
.
Note that Arc.container().requestContext() may return different context based on where you invoke that from. So from within an async observer of that event, you should see it active, but from the thread that fired the even, that depends on whether it was previously active or not. And both of these contexts will have different underlying ContextState.
Got it, thank you.
Describe the bug
my use case:
Currently when gRPC extension is present, security events must be disabled or requests never reach gRPC server endpoint.
When I fire CDI event synchronously or asynchronously, I always get warning log message
Request context already active when gRPC request started
logged several times.When CDI event is fired asynchronously and the CDI request context is activated, it should not be detectable by
Arc.container.request().isActive()
, because if other code re-use the same CDI request context that is also asynchronously deactivated byio.quarkus.arc.impl.EventImpl
, than other code (like the gRPC one) will try to use deactivated context.Expected behavior
CDI request scope deactivation actually deactivates request context.
Actual behavior
Request always goes here https://github.com/quarkusio/quarkus/blob/5290dc7d2968635563d01f13f65c60ac6fc8d9f4/extensions/grpc/runtime/src/main/java/io/quarkus/grpc/runtime/supports/context/GrpcRequestContextGrpcInterceptor.java#L46.
How to Reproduce?
Reproducer:
Another Reproducer :
command
mvn clean verify -DskipTests -f extensions/grpc/ && mvn clean test -f extensions/grpc/deployment/ -Dtest=GrpcAuthUsingSeparatePortTest
finally
clause.https://github.com/quarkusio/quarkus/blob/08bff7a2a239b0e7746f3aeb7d8811b3480a8143/independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/EventImpl.java#L330
io.quarkus.grpc.auth.GrpcAuthTestBase.Service#unaryCall
it is never reached (or logged):And now, you need to ask yourself how do I know it is also related to synchronous events here - you can just comment out this line,
https://github.com/quarkusio/quarkus/blob/08bff7a2a239b0e7746f3aeb7d8811b3480a8143/extensions/security/runtime-spi/src/main/java/io/quarkus/security/spi/runtime/SecurityEventHelper.java#L72
build Security extension and re-run test with a same result.
Output of
uname -a
orver
Fedora 38
Output of
java -version
OpenJDK Runtime Environment Temurin-17.0.7+7
Quarkus version or git rev
999-SNAPSHOT
Build tool (ie. output of
mvnw --version
orgradlew --version
)Apache Maven 3.9.3
Additional information
No response