NR-171475 Prevent AsyncApiImpl from overwriting suspended transactions that are… #1555
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
… already mapped to an AsyncContext
Resolves #1554
With the changes in this PR, the Jetty/Karaf/CamelCXF transactions are reporting with correct times and no transactions are getting suspended and never resumed (which is what was causing a memory leak).
A workaround has been put in place to prevent this specific memory leak condition from being possible. It applies to the legacy async API itself, rather than being Jetty specific, which means that it could address such an issue with a wide range of app servers that are instrumented. To enable the workaround, set the following config to a value of
true
(default isfalse
):Config Option 1: Agent config file (this will update dynamically if the config file is changed)
Config Option 2: System Property
-Dnewrelic.config.legacy_async_api_skip_suspend=true
Config Option 3: Environment Variable
NEW_RELIC_LEGACY_ASYNC_API_SKIP_SUSPEND=true
Discovered a nuance to this while running the
SpringTest.test_spring_webflux_tomcat_webclient_timeout
AIT, which uses embedded Tomcat and the legacy async API. The same transaction instance can be suspended/resumed multiple times and if that is prevented then this AIT will fail (as existing agent behavior is changed).In this particular example, the transaction was initially suspended via a call to
CoyoteAdapter.service
, which the agent instruments:As execution continued the same transaction was resumed and eventually suspended again, this time via a call to
CoyoteAdapter.asyncDispatch
, which the agent also instruments: