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

feat(opentelemetry-sdk-trace-base): Add mandatory forceFlush property to SpanExporter interface #3071

Closed
wants to merge 19 commits into from

Conversation

sgracias1
Copy link
Contributor

@sgracias1 sgracias1 commented Jun 29, 2022

Which problem is this PR solving?

Add optional forceFlush property to SpanExporter interface per spec

Fixes #3067

Short description of the changes

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

added unit tests

Checklist:

  • Followed the style guidelines of this project
  • Unit tests have been added
  • Documentation has been updated

@sgracias1 sgracias1 requested a review from a team June 29, 2022 20:23
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Jun 29, 2022

CLA Signed

The committers listed above are authorized under a signed CLA.

@legendecas
Copy link
Member

legendecas commented Jun 30, 2022

Thank you for your contribution! I think built-in SpanProcessors like BatchSpanProcessor and SimpleSpanProcessor need to adopt the method and invoke the exporter's forceFlush if it exists. Also, would you mind adding some test cases covering the method?

@sgracias1
Copy link
Contributor Author

I see thank you, let me look at the span processors. For the test cases, do mean for testing span processors once the change is made?

@dyladan
Copy link
Member

dyladan commented Jun 30, 2022

I see thank you, let me look at the span processors. For the test cases, do mean for testing span processors once the change is made?

Yes the span processors will need to be tested. There really is no other way to test an interface than to test its implementers.

@codecov
Copy link

codecov bot commented Jun 30, 2022

Codecov Report

Merging #3071 (6c8b184) into main (34c5bdb) will increase coverage by 0.02%.
The diff coverage is 91.66%.

@@            Coverage Diff             @@
##             main    #3071      +/-   ##
==========================================
+ Coverage   93.18%   93.21%   +0.02%     
==========================================
  Files         196      196              
  Lines        6431     6440       +9     
  Branches     1359     1359              
==========================================
+ Hits         5993     6003      +10     
+ Misses        438      437       -1     
Impacted Files Coverage Δ
...y-sdk-trace-base/src/export/ConsoleSpanExporter.ts 81.25% <50.00%> (+2.67%) ⬆️
...ackages/otlp-exporter-base/src/OTLPExporterBase.ts 95.23% <100.00%> (+0.11%) ⬆️
...ckages/opentelemetry-exporter-jaeger/src/jaeger.ts 94.80% <100.00%> (+0.13%) ⬆️
...ckages/opentelemetry-exporter-zipkin/src/zipkin.ts 100.00% <100.00%> (ø)
...-sdk-trace-base/src/export/InMemorySpanExporter.ts 100.00% <100.00%> (ø)
...y-sdk-trace-base/src/export/SimpleSpanProcessor.ts 91.30% <100.00%> (ø)
...-trace-base/src/platform/node/RandomIdGenerator.ts 93.75% <0.00%> (+6.25%) ⬆️

@sgracias1
Copy link
Contributor Author

@legendecas @dyladan
Since we are updating the spec to make forceFlush mandatory what do you think the implementation should look like
Looking at the implementation (ConsoleSpanExporter, InMemorySpanExporter) it seems like it would duplicate what the current shutdown function does or should be a no-op ?

Also looking at BatchSpanProcessorBase, it currently implements forceFlush to call export for each batch, it doesn't seem to make sense to invoke the forceFlush on the exporter (since there shouldn't be anything left to export)

@dyladan
Copy link
Member

dyladan commented Jul 14, 2022

Force flush in the exporter should return a promise which resolves when the currently export completes. If there is no batch currently exporting then it immediately resolves.

@sgracias1
Copy link
Contributor Author

BatchSpanProcessorBase already implements forceFlush. I have not changed it. Should we leave it as is or re-implement that functionality to invoke the exporters forceFlush function?

Making the forceFlush function mandatory required updating a few downstream exporters

  • JaegerExporter
  • ZipkinExporter
  • OTLPExporterBase

I have given these empty implementations for now, does that make sense? I spent a little time looking at these classes but it wasn't obvious to me what the implementation of forceFlush should be for these classes.

Copy link
Member

@dyladan dyladan left a comment

Choose a reason for hiding this comment

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

Please change the title as the interface is no longer optional

@@ -82,6 +82,10 @@ export class JaegerExporter implements SpanExporter {
return this._shutdownOnce.call();
}

forceFlush(): Promise<void> {
return Promise.resolve();
Copy link
Member

Choose a reason for hiding this comment

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

Same as OTLP if it is possible then ForceFlush should only resolve when any in-flight exports are complete.

@@ -109,6 +109,10 @@ export class ZipkinExporter implements SpanExporter {
});
}

forceFlush(): Promise<void> {
return Promise.resolve();
Copy link
Member

Choose a reason for hiding this comment

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

Same here

return this._flush();
}

private _flush(): Promise<void> {
Copy link
Member

Choose a reason for hiding this comment

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

Why have a separate _flush method? Can't shutdown just call ForceFlush?

return this._flush();
}

private _flush(): Promise<void> {
this._finishedSpans = [];
Copy link
Member

Choose a reason for hiding this comment

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

Flushing should not reset. There is a dedicated method for that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@dyladan thank you for the review, can you give your thoughts on BatchSpanProcessorBase (I posted a comment above) should we reimplement it, or leave as is

@sgracias1 sgracias1 changed the title feat(opentelemetry-sdk-trace-base): Add optional forceFlush property to SpanExporter interface feat(opentelemetry-sdk-trace-base): Add mandatory forceFlush property to SpanExporter interface Jul 29, 2022
@dyladan
Copy link
Member

dyladan commented Jul 29, 2022

The batch span processor is specified to not call the exporter multiple times in parallel so you should be able to use forceflush to make sure the export is finished before the next batch is sent.

Comment on lines 118 to 120
.then(() => {
/** ignore resolved values */
});
Copy link
Member

Choose a reason for hiding this comment

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

No need to do .then if you're just going to ignore the value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can remove this, it was mostly a refactor (I moved the code out of the current shutdown function

Copy link
Member

Choose a reason for hiding this comment

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

ah i see. i would just remove it since it doesn't serve a purpose

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Okay I will wrap this in a new promise, returning promise.all wouldn't work with the function type returning a promise

@sgracias1
Copy link
Contributor Author

@dyladan

The batch span processor is specified to not call the exporter multiple times in parallel so you should be able to use forceflush to make sure the export is finished before the next batch is sent.

the current behavior of forceFlush on the processor returns a promise which resolves when all spans have been exported, so we currently

  1. wrap each export(batch) in a promise
  2. promise.all(each export promise)

I don't really see where in this flow we would wan't to add a forceflush call. Do you think something like
1: export(batch)
2: forceflush
3: promise.all(each flush promise)

we do a bit of cleanup when each export completes clearTimeout that I don't quite understand, but it seems like we need to handle the return from each export as well.

@dyladan
Copy link
Member

dyladan commented Aug 1, 2022

The force flush isn't meant to be used in most cases. It is for special situations like shutdown and when you are in an environment that might unexpectedly get frozen or stopped like lambda.

@dyladan
Copy link
Member

dyladan commented Aug 2, 2022

BatchSpanProcessorBase already implements forceFlush. I have not changed it. Should we leave it as is or re-implement that functionality to invoke the exporters forceFlush function?

Making the forceFlush function mandatory required updating a few downstream exporters

  • JaegerExporter
  • ZipkinExporter
  • OTLPExporterBase

I have given these empty implementations for now, does that make sense? I spent a little time looking at these classes but it wasn't obvious to me what the implementation of forceFlush should be for these classes.

I think you can go either way but if you don't implement it please open an issue and we can get it fixed asap

@sgracias1
Copy link
Contributor Author

sgracias1 commented Aug 4, 2022

> I think you can go either way but if you don't implement it please open an issue and we can get it fixed asap

I have updated all the downstream exporters
I am leaving the BatchSpanProcessorBase as is, let me know if you think this needs another issue

Copy link
Member

@legendecas legendecas left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution. Overall LGTM % some nits.

@sgracias1
Copy link
Contributor Author

@legendecas thank you, let me know if the updated pr looks alright to you

@sgracias1
Copy link
Contributor Author

@dyladan can you let me know if this pr looks okay to you now

@github-actions
Copy link

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the stale label Oct 31, 2022
@dyladan dyladan removed the stale label Nov 2, 2022
@github-actions
Copy link

This PR is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the stale label Jan 30, 2023
@legendecas legendecas added sdk:traces Issues and PRs related to the Traces SDK and removed stale labels Jan 31, 2023
@legendecas
Copy link
Member

@dyladan another look at this is appreciated :)

@JacksonWeber
Copy link
Contributor

@sgracias1 Would it be possible for me to pull down your PR and make the appropriate suggested changes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sdk:traces Issues and PRs related to the Traces SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement SpanExporter#forceFlush
5 participants