Skip to content
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

Spring webflux subscribe #190

Merged
merged 3 commits into from
Jan 21, 2021
Merged

Spring webflux subscribe #190

merged 3 commits into from
Jan 21, 2021

Conversation

tspring
Copy link
Contributor

@tspring tspring commented Jan 15, 2021

When calling subscribe on a Mono/Flux, a LambdaSubscriber is created with a new Context. This change inserts a newrelic-token on said Context for the TokenLinkingSubscriber.

I had to split the netty-reactor-0.8.0 instrumentation and create one for 0.9.0, because the earlier versions do not provide an impl of currentContext and we can't indirect weave inherited methods.

I also removed the writeWith and writeAndFlushWith weave methods from spring-webflux, as they were expiring the Token too early and allowing the Transaction to finish before the task was fully complete.

Copy link
Contributor

@jasonjkeller jasonjkeller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on previous discussions and positive feedback on the changes I'm ok with these changes.

Out of curiosity, have any kind of performance tests been run to determine the impact of the additional token creation?

Also, before closing this out it would be great to determine whether or not it also addresses this issue: #125

* * Copyright 2020 New Relic Corporation. All rights reserved.
* * SPDX-License-Identifier: Apache-2.0
*
*/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This header needs to be added to all source files.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it? Some of this code was based off open telemetry instrumentation (as called out in comments and the NOTICE.txt in the root of these modules. Was the omission of these headers in the 0.8.0 module accidental or intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was a bit of both, I'll add the headers to the classes that aren't derived from Otel


import com.newrelic.api.agent.weaver.SkipIfPresent;

@SkipIfPresent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's going on here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In reactor-netty versions prior to 0.9.0, LambdaSubscriber::currentContext is implemented in the super class, which we can't weave so we needed to split the instrumentation. This is to prevent netty-reactor-0.8 from applying to 0.9+ and effectively double weaving.

// to be linked by TokenLinkingSubscriber but expired on onComplete here
if (AgentBridge.getAgent().getTransaction(false) != null
&& initialContext.getOrDefault("newrelic-token", null) == null) {
nrContext = Context.of("newrelic-token", NewRelic.getAgent().getTransaction().getToken());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we discussed naming this newrelic-token field to something else to disambiguate it from the key of the other context.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing so made the code considerably more complicated and brittle. This way we continue to use the TokenLinkingSubscriber rather a new Subscriber.

}
return Weaver.callOriginal();
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the expiring of tokens you said was being done defensively, but which not actually needed, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it turns out that the writeWith and writeAndFlushWith can get called during the reactive flow which prevents further operations from linking the token and effectively ending the Transaction early.

@tspring tspring merged commit 0d8d810 into main Jan 21, 2021
@tspring tspring deleted the spring-webflux-subscribe branch January 21, 2021 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants