-
Notifications
You must be signed in to change notification settings - Fork 324
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
Added (initial) support for compressing spans #2477
Conversation
👋 @tobiasstadler Thanks a lot for your contribution! It may take some time before we review a PR, so even if you don’t see activity for some time, it does not mean that we have forgotten about it. Every once in a while we go through a process of prioritization, after which we are focussing on the tasks that were planned for the upcoming milestone. The prioritization status is typically reflected through the PR labels. It could be pending triage, a candidate for a future milestone, or have a target milestone set to it. |
private final ConfigurationOption<Boolean> spanCompressionEnabled = ConfigurationOption.booleanOption() | ||
.key("span_compression_enabled") | ||
.configurationCategory(CORE_CATEGORY) | ||
.tags("added[1.30.0]", "internal") |
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.
beac422
to
dbc556e
Compare
Thanks for your PR! Note that @jackshirazi is already working on this, so please coordinate before proceeding. @AlexanderWert has now implemented a status indicator in the corresponding issue (#1847) so that it's easier to spot if something is in progress already. |
@tobiasstadler please could you confirm I have the correct connection in Slack |
@jackshirazi You pinged the correct person |
apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/SpanConfiguration.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/SpanConfiguration.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/SpanConfiguration.java
Show resolved
Hide resolved
30e9427
to
a11c04f
Compare
…istent span compression
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Span.java
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Span.java
Outdated
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Span.java
Outdated
Show resolved
Hide resolved
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Span.java
Outdated
Show resolved
Hide resolved
fdbbda9
to
32e720b
Compare
apm-agent-core/src/main/java/co/elastic/apm/agent/impl/transaction/Span.java
Outdated
Show resolved
Hide resolved
apm-agent-core/src/test/java/co/elastic/apm/agent/impl/transaction/SpanCompressionIT.java
Show resolved
Hide resolved
apm-agent-core/src/test/java/co/elastic/apm/agent/impl/transaction/SpanCompressionIT.java
Show resolved
Hide resolved
...ore/src/test/java/co/elastic/apm/agent/impl/transaction/SameKindCompressionStrategyTest.java
Show resolved
Hide resolved
/test |
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.
Great work, thank you!
@elasticmachine run elasticsearch-ci/docs |
Thank You! |
@@ -292,13 +303,146 @@ public void beforeEnd(long epochMicros) { | |||
|
|||
@Override | |||
protected void afterEnd() { | |||
this.tracer.endSpan(this); | |||
if (transaction != null && transaction.isSpanCompressionEnabled() && parent != null) { | |||
Span buffered = parent.bufferedSpan.get(); |
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.
Seems like this may lead to multiple threads concurrently having access to the buffered span instance.
In my initial POC for span compression, I tried to avoid that by atomically getting and removing the buffered span or setting it to the current span if there's no buffered span.
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.
Multiple threads can concurrently have access, that's okay here. It is resolved at the update or report stage which you can fully reason about here (nice when it's concurrent). There are 3 possible atomic concurrent updates, and in each case either it succeeds (true) or fails (false). The cases are complete
buffer -> null
true: report buffer
false: do nothing
null -> this
true: do nothing
false: report this
buffer -> this
true: report buffer
false: report this
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.
Yes, concurrent access is fine here and also covered by tests.
return isExit() && isDiscardable() && (outcomeNotSet() || getOutcome() == Outcome.SUCCESS); | ||
} | ||
|
||
private boolean tryToCompress(Span sibling) { |
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.
Seems like this method could also be simplified when we can guarantee that we have exclusive access to both this
span and the sibling. (see above linked POC)
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.
@felixbarny I agree your solution was the more elegant one. I decided that in the high contention case (which is really when these alternatives matter) we want to avoid the backoff and retry loop, ie that under conflict it's better to drop the compression and allow the thread to proceed asap rather than maximally try to compress. So felt this solution was acceptable
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.
note the loops in the try are getting maxes after compression has succeeded, so should not really cause contention, but we may need to review
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 explaining, makes sense. I agree that the approach taken in this PR is probably the one that causes less contention. I find it a little harder to reason about and verify correctness as there's more that can happen concurrently. But from what I can tell, it seems like all the cases are handled properly.
What does this PR do?
Fixes #1847
Checklist