-
Notifications
You must be signed in to change notification settings - Fork 913
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
Ensure tilde$1 onExit is run in correct order #13360
Ensure tilde$1 onExit is run in correct order #13360
Conversation
dbdb128
to
6b91cd1
Compare
0a6dbbf
to
1184b41
Compare
...javaagent/instrumentation/pekkohttp/v1_0/server/route/RouteConcatenationInstrumentation.java
Outdated
Show resolved
Hide resolved
If you guys are happy with this, I can make a similar change to the Akka instrumentation: the same race condition exists within its |
how hard would it be to add a test for this? thanks |
(if you rebase, we've fixed the CI failure that you're seeing) |
1184b41
to
24cfb17
Compare
@trask I just played around with this for a bit and I'm having a difficult time reproducing this using straight pekko code; it might be difficult to write a failing test without introducing the tapir-pekko module as it's only with this construction of the route that the issue is triggered (at least as far I've experienced). |
...javaagent/instrumentation/pekkohttp/v1_0/server/route/RouteConcatenationInstrumentation.java
Outdated
Show resolved
Hide resolved
public static void onExit( | ||
@Advice.Argument(value = 2) RequestContext ctx, | ||
@Advice.Return(readOnly = false) Future<RouteResult> fut) { | ||
fut = fut.andThen(new OnExitFinalizer(), ctx.executionContext()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This advice will apply also when the original method threw an exception because of the onThrowable = Throwable.class
. Perhaps it would be better to write this as
public static void onExit(
@Advice.Argument(value = 2) RequestContext ctx,
@Advice.Return(readOnly = false) Future<RouteResult> future,
@Advice.Thrown Throwable throwable) {
if (throwable != null) {
PekkoRouteHolder.restore();
} else {
future = future.andThen(new OnExitFinalizer(), ctx.executionContext());
}
I don't know how scala futures work but in java CompletableFuture
the methods starting with then
only apply when the future completes successfully. With CompletableFuture
whenComplete
would be a better choice. Please check whether andThen
also runs when the future does not complete normally.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
andThen
will be evaluated regardless of how the Future
completes: the input of this supplied function to andThen
takes a Try
which models both success and failures, and the function we supply executes PekkoRouteHolder.restore()
regardless of the input; e.g., we unconditionally restore regardless of how the Future
completed. Importantly, andThen
doesn't affect the return value of the Future
and swallows any exceptions thrown within the supplied function. If I understand the above correctly, I believe this does what we want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for confirming this.
If you are reluctant to add extra dependencies you could add a separate test suite (search for |
a6307fd
to
2a8c4ad
Compare
@laurit I ended up adding the tapir-pekko-http dependency as a |
2a8c4ad
to
d78981a
Compare
1fc769c
to
8eac124
Compare
Prior to adding the on exit finalization logic to the Future, this test failed because of an NPE thrown because PekkoRouteHolder.restore was called in the wrong order.
8eac124
to
ced90a6
Compare
@trask Do you have a sense of when this will be released? |
Second half of next week |
Resolves #13049