Skip to content

Prevent public API related spans from being recycled#1859

Merged
eyalkoren merged 10 commits intoelastic:masterfrom
eyalkoren:public-api-reference-counting
Jun 17, 2021
Merged

Prevent public API related spans from being recycled#1859
eyalkoren merged 10 commits intoelastic:masterfrom
eyalkoren:public-api-reference-counting

Conversation

@eyalkoren
Copy link
Contributor

@eyalkoren eyalkoren commented Jun 14, 2021

What does this PR do?

In order to work around misuse of the public activation API, related spans will not be recycled.
This way we can ensure there is no improper usage of recycled-and-still-referenced span objects at the cost of creating some garbage.

Checklist

  • This is an enhancement of existing features, or a new feature in existing plugins
    • I have updated CHANGELOG.asciidoc
    • I have added tests that prove my fix is effective or that my feature works
    • I have made corresponding changes to the documentation

I decided not to add anything to the documentation about that, as I think it would only cause confusion.

@ghost
Copy link

ghost commented Jun 14, 2021

💚 Build Succeeded

the below badges are clickable and redirect to their specific view in the CI or DOCS
Pipeline View Test View Changes Artifacts preview

Expand to view the summary

Build stats

  • Build Cause: Pull request #1859 updated

  • Start Time: 2021-06-17T11:32:59.431+0000

  • Duration: 51 min 27 sec

  • Commit: 3463919

Test stats 🧪

Test Results
Failed 0
Passed 2246
Skipped 18
Total 2264

Trends 🧪

Image of Build Times

Image of Tests

💚 Flaky test report

Tests succeeded.

Expand to view the summary

Test stats 🧪

Test Results
Failed 0
Passed 2246
Skipped 18
Total 2264

@eyalkoren eyalkoren requested a review from SylvainJuge June 16, 2021 05:51
@eyalkoren eyalkoren requested a review from SylvainJuge June 17, 2021 06:06
Copy link
Member

@SylvainJuge SylvainJuge left a comment

Choose a reason for hiding this comment

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

LGTM, I'm fine with having webflux test app rely on internal API for now, we can revisit this later if required to. 99.99% of the time this app will only be used for unit testing.

@eyalkoren eyalkoren merged commit 39df5bf into elastic:master Jun 17, 2021
@eyalkoren eyalkoren deleted the public-api-reference-counting branch June 17, 2021 13:05

@Advice.OnMethodEnter(suppress = Throwable.class, inline = false)
public static void incrementReferences(@Advice.Argument(0) Object span) {
((AbstractSpan<?>) span).incrementReferences();
Copy link
Member

Choose a reason for hiding this comment

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

Have you considered instrumenting AbstractSpanImpl directly and incrementing the reference there? The advantage is that would also work with older versions of the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If you mean the constructor, then - yes, I considered but preferred this.
As far as I see it - there is no problem to any current API user (besides the one that reported this issue) and all future users will use the newer API version.

Copy link
Member

Choose a reason for hiding this comment

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

👌

@CoderLan0668
Copy link
Contributor

Using the public api to develop an external plugin, but an error was thrown in unit test:
image

the problem was caused by the invoking of the public api co.elastic.apm.api.ElasticApm#currentSpan , which will incrementReferences .

In order to work around misuse of the public activation API, related spans will not be recycled.

i think this PR is terrible, as it makes the RecyclingValidation become invalid.

So what should i do now, just disable the RecyclingValidation like this PR do?

@eyalkoren
Copy link
Contributor Author

Thanks for the honest feedback.

We've seen enough misuse that caused a lot of grief to our community, which made us decide that the performance gains of recycling do not worth the pain, only in the narrow context of public API spans/transactions.
The problem with recycled "dirty" spans is that they may be reused while still containing irrelevant data, which can be very difficult to debug, or even track.

This PR only makes sure that spans/transactions "touched" by the public API pass away in the natural Java way, which is garbage collection, instead of being recycled. So if your recycling validation would have passed, that would be a bug in this PR that requires fixing 🙂 .

So what should i do now, just disable the RecyclingValidation like this PR do?

Yes, for the time being.
We intend to put more efforts soon to expose all our testing capabilities better for external plugins developers, so if I am to get something constructive from your feedback, that would be to add an abstract test class for external plugins that disables this check. Would that be a good solution in your opinion?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

4 participants