-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Quarkus test hangs forever with a ResteasyReactiveClientRequestFilter and Stork #27337
Comments
You added a link to a Zulip discussion, please make sure the description of the issue is comprehensive and doesn't require accessing Zulip.
|
|
I spent a few hours on it and so far have no clue. BTW, @vsevel is the idea to use the filter for the actual client and the client used by the service discovery? |
thanks @michalszynkiewicz for spending some time already. |
the issue is that I have weird behaviors on other calls too, not just on the discovery service.
and I have started excluding explicit calls from the filter. but that does not bring a high level of confidence. |
That call just checks that you are not on an event loop. This seems to be the case for the second call. Suspending the request may prevent the body from being read, which could be a problem. |
I guess I am missing the idiomatic construct. my requirement is simply to be able to intercept outgoing calls, adding some attributes in the header based on the injected
in my example, the first call is happening on the main thread (this is triggered from a test). I use the
not sure what you mean. I strictly applied the approach taken in the oidc reactive filter. what is the proper way to exercise the |
Looking into it. |
The exception is swallowed:
|
You cannot access the |
BTW, it's a synchronous exception that is swallowed, something should be added to RR to log the exception. Most probably in org.jboss.resteasy.reactive.client.handlers.ClientRequestFilterRestHandler. |
@michalszynkiewicz @vsevel
I just added the The following solution is probably better as it clearly identifies the boundary: package org.acme;
import javax.enterprise.context.control.ActivateRequestContext;
import javax.enterprise.inject.spi.CDI;
import javax.inject.Inject;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import io.quarkus.arc.Arc;
import io.quarkus.security.identity.CurrentIdentityAssociation;
import io.quarkus.security.identity.SecurityIdentity;
import io.smallrye.mutiny.Uni;
import org.jboss.resteasy.reactive.client.spi.ResteasyReactiveClientRequestContext;
import org.jboss.resteasy.reactive.client.spi.ResteasyReactiveClientRequestFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Provider
public class MyReactiveRequestFilter implements ResteasyReactiveClientRequestFilter {
private static final Logger log = LoggerFactory.getLogger(MyReactiveRequestFilter.class);
@Inject
CurrentIdentityAssociation currentIdentityAssociation;
@Override
public void filter(ResteasyReactiveClientRequestContext requestContext) {
boolean requestScopeActivated = false;
if (! Arc.container().requestContext().isActive()) {
Arc.container().requestContext().activate();
requestScopeActivated = true;
}
log.info("processing " + requestContext.getUri() + "; suspend request context");
requestContext.suspend();
try {
boolean shouldTerminateRequestScope = requestScopeActivated;
currentIdentityAssociation.getDeferredIdentity()
.subscribe()
.with(securityIdentity -> {
log.info("anonymous = " + securityIdentity.isAnonymous());
deactivateRequestScopeIfNeeded(shouldTerminateRequestScope);
requestContext.resume();
},
throwable -> {
log.error("filter failed", throwable);
deactivateRequestScopeIfNeeded(shouldTerminateRequestScope);
requestContext.abortWith(Response.status(500).build());
requestContext.resume();
});
} catch (Throwable e) {
log.error("Something really bad happened and get buried real deep", e);
requestContext.abortWith(Response.status(500).build());
requestContext.resume();
}
}
private void deactivateRequestScopeIfNeeded(boolean shouldTerminateRequestScope) {
if (shouldTerminateRequestScope) {
Arc.container().requestContext().deactivate();
}
}
} |
ok. just a bit over my head ;-) it is strange to me to force the activation of the request context.
|
Your approach is fine! |
When |
out of curiosity, what is the purpose of |
In REST Client Reactive, the "usual" filter is (at least in some situations) called on the event loop. |
It looks like the problem is in the fact that an exception is thrown (and the rest client handler schedules processing it) while the request context is suspended. requestContext.suspend();
try {
currentIdentityAssociation.getDeferredIdentity().subscribe()
.with(securityIdentity -> {
log.info("anonymous = " + securityIdentity.isAnonymous());
requestContext.resume();
},
throwable -> {
log.error("filter failed", throwable);
requestContext.abortWith(Response.status(500).build());
requestContext.resume();
});
} catch (Exception any) {
requestContext.resume();
} It still needs to be fixed in the handler, at least by logging some error, so that users know that they have to handle such exceptions |
may be a finally would be better?
or is this problematic since the subscribers may not have executed yet, and we could end up executing the resume from the finally before the resume from the subscribers? I see
so if we do not perform any blocking operation, then request/resume is not required I take it. |
Exactly |
With the linked PR the error will be logged and the processing will continue resulting in I'm not 100% sure it's proper though, let's see what people who worked more on the internals think ;) |
ok so may be something like this then:
|
Yes, I forgot about rethrowing in my snippet above :) |
so I think we are at the end of this thread. thanks so much for your attention @michalszynkiewicz and @cescoffier . I have a much better understanding now. this was really a learning experience. |
let's close it then, thanks in advance for the chocolate bar :D |
refs quarkusio#27337 (cherry picked from commit 3e7ceb9)
Describe the bug
I have written a client request filter followingup the
OidcClientRequestReactiveFilter
example for suspending/resuming the context in a reactive context.In my case I am using the following filter implementation, and a pseudo remote custom discovery resource, called from the stork client side representation.
cc @geoand @michalszynkiewicz @sberyozkin
Expected behavior
Test
Stork3Test
should succeed.Actual behavior
The tests hangs forever after printing:
How to Reproduce?
mvn package -Dtest=Stork3Test
in project reproducer_reactive_storkOutput of
uname -a
orver
No response
Output of
java -version
No response
GraalVM version (if different from Java)
No response
Quarkus version or git rev
2.11.2
Build tool (ie. output of
mvnw --version
orgradlew --version
)No response
Additional information
see this thread
The text was updated successfully, but these errors were encountered: