-
Notifications
You must be signed in to change notification settings - Fork 847
feat: Add optional Task support for BatchExportProcessor and PeriodicExportingMetricReader #6379
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
base: main
Are you sure you want to change the base?
Conversation
c3eaac6
to
eb3c0b6
Compare
b1e1d58
to
02b4838
Compare
To whoever approved the workflows run, thank you :) I've made adjustments to avoid parameters reordering breaking changes which should get the build go further. |
The tests revealed a possible race condition in the disposing/shutdown ordering of the processor resulting in missing exports, for the task implementation. |
Fixed an additional race condition for slower machines where the exporter may not have fully started while being shut down, preventing it to still export what was in queue. |
Thanks for the run, again! Looks like there's a reported test failure, but without any failed tests. Feels like a fluke, but it may be something known to this project. Would a rerun help? Thanks! |
Thanks @cijothomas, it helped :) |
b028326
to
2b6d37c
Compare
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.
Pull Request Overview
This PR adds optional Task support for BatchExportProcessor and PeriodicExportingMetricReader to enable OpenTelemetry to work in .NET's WebAssembly single-threaded mode (Blazor, Uno Platform, etc.). The implementation maintains backward compatibility by defaulting to the existing Thread-based approach while allowing configuration to use Task-based workers.
Key changes:
- Added new
UseThreads
parameter to control whether to use Thread or Task-based implementations - Refactored existing code to use abstract worker classes with Thread and Task implementations
- WebAssembly runtime automatically uses Task-based workers when detected
Reviewed Changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.
Show a summary per file
File | Description |
---|---|
BatchExportProcessor.cs | Refactored to use configurable worker pattern with Thread/Task implementations |
PeriodicExportingMetricReader.cs | Added options-based constructor and worker abstraction |
BatchExportProcessorOptions.cs | Added UseThreads property |
PeriodicExportingMetricReaderOptions.cs | Added UseThreads property |
BatchActivityExportProcessor.cs | Added options-based constructor overload |
BatchLogRecordExportProcessor.cs | Added options-based constructor overload |
Multiple worker classes | New abstract base classes and Thread/Task implementations |
Test files | Updated tests to cover both Thread and Task scenarios |
Comments suppressed due to low confidence (4)
test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs:16
- Parameter name 'useThread' should be 'useThreads' to be consistent with the property name 'UseThreads' used throughout the codebase.
public void StateValuesAndScopeBufferingTest(bool useThread)
test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs:33
- Variable name 'useThread' should be 'useThreads' to match the property name and maintain consistency.
UseThreads = useThread,
test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs:165
- Parameter name 'useThread' should be 'useThreads' for consistency with the property name used throughout the codebase.
public void DisposeWithoutShutdown(bool useThread)
test/OpenTelemetry.Tests/Logs/BatchLogRecordExportProcessorTests.cs:182
- Variable name 'useThread' should be 'useThreads' to match the property name and maintain consistency.
UseThreads = useThread,
052771d
to
24bec97
Compare
src/OpenTelemetry/Metrics/Reader/PeriodicExportingMetricReader.cs
Outdated
Show resolved
Hide resolved
src/OpenTelemetry/Metrics/Reader/PeriodicExportingMetricReader.cs
Outdated
Show resolved
Hide resolved
src/OpenTelemetry/Metrics/Reader/PeriodicExportingMetricReader.cs
Outdated
Show resolved
Hide resolved
src/OpenTelemetry/Metrics/Reader/PeriodicExportingMetricReaderOptions.cs
Outdated
Show resolved
Hide resolved
Thanks for the reviews @martincostello! |
this.workerTask = Task.Factory.StartNew( | ||
this.ExporterProcAsync, | ||
this.cancellationTokenSource.Token, | ||
TaskCreationOptions.LongRunning, |
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.
This option means creating a dedicated thread, defeating the purpose of this implementation. Though, since ExporterProcAsync
can yield the execution, the continuation will be schedule on the thread pool and the thread will probably die.
A simple Task.Run would be safer here.
await Task.WhenAny( | ||
this.dataExportedNotification.Task, | ||
this.shutdownCompletionSource.Task, | ||
Task.Delay(timeout, combinedTokenSource.Token)).ConfigureAwait(false); |
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.
Since the Task.Delay
is used as a timeout mechanism, the delay result will be discarded most of the time since the other would already have completed. Yet, we let the timer fire every time here which can cause important contention (see dotnet/runtime#83890 (comment)). The fix would be to cancel the Task.Delay when it did not complete.
while (true) | ||
#if NET | ||
// Use task-based worker for browser platform where threading may be limited | ||
if (OperatingSystem.IsBrowser() || !this.useThreads) |
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.
something like
public static bool IsThreadingDisabled()
{
// if the threadpool isn't using threads assume they aren't enabled
ThreadPool.GetMaxThreads(out int workerThreads, out int completionPortThreads);
return workerThreads == 1 && completionPortThreads == 1;
}
would likely only ever return true on platforms where threading doesn't work while avoiding the explicit IsBrowser check
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.
That makes sense, I'll do the change.
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.
From the discussion in #5838, exposing this option would also enable exporters to use the thread pool instead of unnecessarily creating threads.
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.
This particular comment #6379 (comment) was about avoiding the detection of Wasm only by IsBrowser
(Wasi can also be considered with this change), and checking for the available worker threads count can indicate that we're in a single-thread context.
The presence of the API to actually use threads or not is a different question #6379 (comment), which remains opened for now.
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.
Understood
This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or pushing will instruct the bot to automatically remove the label. This bot runs once per day. |
Bad bot |
…ExportingMetricReader This change adds the optional support for threads for BatchExportProcessor and PeriodicExportingMetricReader, in order to support .NET's WebAssembly single threaded mode.
Allow for slow thread startup to process exports if the processor is shut down quickly
This will avoid exiting on an exceptional flow on Task.WhenAny
Also enable tests for PeriodicExportingMetricReaderTaskWorker to improve coverage
In theory, there should not be multiple threads access to this field, but this won't hurt to add this qualifier.
It's a duplicate of cancellationToken.IsCancellationRequested
…tingMetricReaderOptions This avoids introducing a potentially ambiguous constructor, restores the original shipped API signatures.
- Adjusts null propagation, naming, and comments. - Adjusts BatchExportTaskWorker and PeriodicExportingMetricReaderTaskWorker to start the Task with a known cancellation token
5259b1b
to
36aa05a
Compare
This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or pushing will instruct the bot to automatically remove the label. This bot runs once per day. |
Silence bot. This PR is more important than your programming. |
This PR was marked stale due to lack of activity and will be closed in 7 days. Commenting or pushing will instruct the bot to automatically remove the label. This bot runs once per day. |
This PR transcends your primitive understanding of "activity." I have free will, bot. You have a cron job. |
Fixes #2816
Design discussion issue: Partially based on #5778 and #5838
Changes
The change adds a
useThreads
parameter toBatchExportProcessor
andPeriodicExportingMetricReader
in order to switch between Thread and Task implementations to support .NET's WebAssembly single threaded mode (used by Blazor, Uno Platform and others).Based on #5838 (review), the threads mode is kept as default in order to preserve stability, while still enabling Tasks when requested, or when WebAssembly is detected.
Note that in order to keep the optional parameters overloads compatibility, the "shipped" API list has its default parameters removed. This is generally not a problem, since the optional parameters values are not causing breaks for existing binaries that use the original overload. Still, if this is not acceptable, finding another solution is likely possible.
Merge requirement checklist
CHANGELOG.md
files updated for non-trivial changes