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

perf(opentelemetry): Bucket spans for cleanup #14154

Merged
merged 9 commits into from
Nov 27, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add comment explaining
  • Loading branch information
lforst committed Nov 14, 2024
commit 877e8f52ff082cfc8f8b4bef4187faa1bc1fc5c2
17 changes: 17 additions & 0 deletions packages/opentelemetry/src/spanExporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ interface FinishedSpanBucket {
*/
export class SentrySpanExporter {
private _flushTimeout: ReturnType<typeof setTimeout> | undefined;

/*
* A quick explanation on the buckets: We do bucketing of finished spans for efficiency. This span exporter is
* accumulating spans until a root span is encountered and then it flushes all the spans that are descendants of that
* root span. Because it is totally in the realm of possibilities that root spans are never finished, and we don't
* want to accumulate spans indefinitely in memory, we need to periodically evacuate spans. Naively we could simply
* store the spans in an array and each time a new span comes in we could iterate through the entire array and
* evacuate all spans that have an end-timestamp that is older than our limit. This could get quite expensive because
* we would have to iterate a potentially large number of spans every time we evacuate. We want to avoid these large
* bursts of computation.
*
* Instead we go for a bucketing approach and put spans into buckets, based on what second
* (modulo the time limit) the span was put into the exporter. With buckets, when we decide to evacuate, we can
* iterate through the bucket entries instead, which have an upper bound of items, making the evacuation much more
* efficient. Cleaning up also becomes much more efficient since it simply involves de-referencing a bucket within the
* bucket array, and letting garbage collection take care of the rest.
*/
private _finishedSpanBuckets: (FinishedSpanBucket | undefined)[];
mydea marked this conversation as resolved.
Show resolved Hide resolved
private _finishedSpanBucketSize: number;
private _spansToBucketEntry: WeakMap<ReadableSpan, FinishedSpanBucket>;
Expand Down