Skip to content

Commit

Permalink
perf(export): do not allocate arrays if resource has no pending async…
Browse files Browse the repository at this point in the history
… attributes (#4550)

* perf(eport): do not allocate arrays if resource has no pending async attributes

* perf(export): do not use splice if fit in one batch

* Update CHANGELOG.md

Co-authored-by: Marc Pichler <marc.pichler@dynatrace.com>

---------

Co-authored-by: Marc Pichler <marc.pichler@dynatrace.com>
  • Loading branch information
Samuron and pichlermarc authored Mar 25, 2024
1 parent f9a0d3e commit 5fb65b4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 10 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ For experimental package changes, see the [experimental CHANGELOG](experimental/

### :rocket: (Enhancement)

* perf(sdk-trace-base): do not allocate arrays if resource has no pending async attributes

### :bug: (Bug Fix)

* fix(sdk-metrics): increase the depth of the output to the console such that objects in the metric are printed fully to the console [#4522](https://github.com/open-telemetry/opentelemetry-js/pull/4522) @JacksonWeber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,13 @@ export abstract class BatchSpanProcessorBase<T extends BufferConfig>
// Reset the finished spans buffer here because the next invocations of the _flush method
// could pass the same finished spans to the exporter if the buffer is cleared
// outside the execution of this callback.
const spans = this._finishedSpans.splice(0, this._maxExportBatchSize);
let spans: ReadableSpan[];
if (this._finishedSpans.length <= this._maxExportBatchSize) {
spans = this._finishedSpans;
this._finishedSpans = [];
} else {
spans = this._finishedSpans.splice(0, this._maxExportBatchSize);
}

const doExport = () =>
this._exporter.export(spans, result => {
Expand All @@ -195,19 +201,24 @@ export abstract class BatchSpanProcessorBase<T extends BufferConfig>
);
}
});
const pendingResources = spans
.map(span => span.resource)
.filter(resource => resource.asyncAttributesPending);

let pendingResources: Array<Promise<void>> | null = null;
for (let i = 0, len = spans.length; i < len; i++) {
const span = spans[i];
if (
span.resource.asyncAttributesPending &&
span.resource.waitForAsyncAttributes
) {
pendingResources ??= [];
pendingResources.push(span.resource.waitForAsyncAttributes());
}
}

// Avoid scheduling a promise to make the behavior more predictable and easier to test
if (pendingResources.length === 0) {
if (pendingResources === null) {
doExport();
} else {
Promise.all(
pendingResources.map(
resource => resource.waitForAsyncAttributes?.()
)
).then(doExport, err => {
Promise.all(pendingResources).then(doExport, err => {
globalErrorHandler(err);
reject(err);
});
Expand Down

0 comments on commit 5fb65b4

Please sign in to comment.