-
Notifications
You must be signed in to change notification settings - Fork 1k
feat(sdk-metrics): align PeriodicMetricReader export timeout semantics #8684
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?
Changes from all commits
41910f3
e371867
d3fc20b
b78cae9
1b69dec
c3b8e7f
7d07ef8
bc2f19d
b25a0bb
acca5b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,6 @@ | ||
| Comparing source compatibility of opentelemetry-sdk-metrics-1.65.0-SNAPSHOT.jar against opentelemetry-sdk-metrics-1.64.0.jar | ||
| *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder (not serializable) | ||
| === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 | ||
| +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder setExporterTimeout(long, java.util.concurrent.TimeUnit) | ||
| +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder setExporterTimeout(java.time.Duration) | ||
| +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder setInternalTelemetryVersion(io.opentelemetry.sdk.common.InternalTelemetryVersion) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,13 +24,16 @@ | |
| public final class PeriodicMetricReaderBuilder { | ||
|
|
||
| static final long DEFAULT_SCHEDULE_DELAY_MINUTES = 1; | ||
| static final int DEFAULT_EXPORT_TIMEOUT_MILLIS = 30_000; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding a default timeout when none exists today is problematic, since it can change behavior that has been otherwise working. We either have to call the lack of a timeout a bug, or be more conservative and set the default timeout to the interval when the user doesn't explicitly set it.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @jack-berg sir or the feedback. I’ve addressed the API review comments, generated the API diff, and added tests for the new timeout API. I also updated the timeout implementation to avoid blocking the PeriodicMetricReader scheduler while preserving asynchronous batching and handling shutdown/final export safely. The full CI matrix is now passing. I’d appreciate your review of the updated implementation.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is not addressed. To address, you would need to leave exporterTimeoutNanos as null, and resolve the value conditionally in build(). |
||
|
|
||
| private final MetricExporter metricExporter; | ||
|
|
||
| private InternalTelemetryVersion internalTelemetryVersion = InternalTelemetryVersion.LATEST; | ||
|
|
||
| private long intervalNanos = TimeUnit.MINUTES.toNanos(DEFAULT_SCHEDULE_DELAY_MINUTES); | ||
|
|
||
| @Nullable private Long exporterTimeoutNanos; | ||
|
|
||
| @Nullable private ScheduledExecutorService executor; | ||
|
|
||
| private int maxExportBatchSize; | ||
|
|
@@ -57,6 +60,26 @@ public PeriodicMetricReaderBuilder setInterval(Duration interval) { | |
| return setInterval(interval.toNanos(), TimeUnit.NANOSECONDS); | ||
| } | ||
|
|
||
| /** | ||
| * Sets the timeout for the underlying exporter. If unset, defaults to {@value | ||
| * DEFAULT_EXPORT_TIMEOUT_MILLIS}ms. | ||
| */ | ||
| public PeriodicMetricReaderBuilder setExporterTimeout(long timeout, TimeUnit unit) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is new public API surface area, which comes with new content checks into Also, you'll see failing tests if you run the build. You'll want to fix those failing tests, and add new tests for this specific feature. |
||
| requireNonNull(unit, "unit"); | ||
| checkArgument(timeout >= 0, "timeout must be non-negative"); | ||
| exporterTimeoutNanos = timeout == 0 ? Long.MAX_VALUE : unit.toNanos(timeout); | ||
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Sets the timeout for the underlying exporter. If unset, defaults to {@value | ||
| * DEFAULT_EXPORT_TIMEOUT_MILLIS}ms. | ||
| */ | ||
| public PeriodicMetricReaderBuilder setExporterTimeout(Duration timeout) { | ||
| requireNonNull(timeout, "timeout"); | ||
| return setExporterTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS); | ||
| } | ||
|
|
||
| /** Sets the {@link ScheduledExecutorService} to schedule reads on. */ | ||
| public PeriodicMetricReaderBuilder setExecutor(ScheduledExecutorService executor) { | ||
| requireNonNull(executor, "executor"); | ||
|
|
@@ -83,10 +106,17 @@ public PeriodicMetricReader build() { | |
| ScheduledExecutorService executor = this.executor; | ||
| if (executor == null) { | ||
| executor = | ||
| Executors.newScheduledThreadPool(1, new DaemonThreadFactory("PeriodicMetricReader")); | ||
| Executors.newScheduledThreadPool(2, new DaemonThreadFactory("PeriodicMetricReader")); | ||
| } | ||
| return new PeriodicMetricReader( | ||
| metricExporter, intervalNanos, executor, maxExportBatchSize, internalTelemetryVersion); | ||
| metricExporter, | ||
| intervalNanos, | ||
| exporterTimeoutNanos != null | ||
| ? exporterTimeoutNanos | ||
| : Math.min(intervalNanos, TimeUnit.MILLISECONDS.toNanos(DEFAULT_EXPORT_TIMEOUT_MILLIS)), | ||
| executor, | ||
| maxExportBatchSize, | ||
| internalTelemetryVersion); | ||
| } | ||
|
|
||
| /** Sets the internal telemetry version used to control self-observability metrics. */ | ||
|
|
||
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.