Skip to content

PeriodicExportingMetricReader discards its shutdown timeout - #5575

Open
dwin-gharibi wants to merge 2 commits into
open-telemetry:mainfrom
dwin-gharibi:fix/periodic-reader-shutdown-timeout
Open

PeriodicExportingMetricReader discards its shutdown timeout#5575
dwin-gharibi wants to merge 2 commits into
open-telemetry:mainfrom
dwin-gharibi:fix/periodic-reader-shutdown-timeout

Conversation

@dwin-gharibi

Copy link
Copy Markdown

Closes #5574.

Description

PeriodicExportingMetricReader.shutdown works out how much of the caller's budget is left after joining the ticker thread, then passes it to the exporter as timeout=. Every MetricExporter.shutdown is declared as shutdown(self, timeout_millis=30_000, **kwargs), so the value is absorbed by **kwargs and discarded, and the exporter falls back to its own 30 second default.

The force_flush call three lines below correctly uses timeout_millis=, which is what marks this as a slip rather than a deliberate choice.

Root cause

opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py:541. The keyword is timeout= where the exporter protocol declares timeout_millis=.

Approach

Rename the keyword to timeout_millis, and clamp the computed value at zero. The clamp is not cosmetic: joining the ticker thread on the preceding line can consume the entire budget, which would otherwise hand the exporter a negative timeout - a case the new tests cover explicitly.

Files changed

  • opentelemetry-sdk/src/opentelemetry/sdk/metrics/_internal/export/__init__.py
  • opentelemetry-sdk/tests/metrics/test_periodic_exporting_metric_reader.py
  • .changelog/5564.fixed

Testing

Four tests drive MeterProvider.shutdown with a recording exporter and assert the exporter receives the budget as timeout_millis, that **kwargs is empty, and that the exporter's own 30s default is not used.

The clamp test drives reader.shutdown(timeout_millis=0) directly, because MeterProvider.shutdown enforces its own deadline first and would never reach the reader.

Result: 859 passed in opentelemetry-sdk (855 baseline plus 4 new).

Risk / compatibility

Exporters now receive the timeout they were always meant to receive. An exporter that genuinely uses its budget will return sooner than before, which is the point; an exporter that ignores timeout_millis is unaffected. No public signature changes.

Every MetricExporter.shutdown signature is
shutdown(self, timeout_millis=30_000, **kwargs), so a budget passed under any
other keyword lands in **kwargs and the exporter silently falls back to its
own 30s default.

Assert the exporter receives the remaining budget as timeout_millis, that
nothing is swallowed into **kwargs, that the default is not used, and that an
already-exhausted budget clamps at zero rather than going negative.

These tests fail against the current implementation.
PeriodicExportingMetricReader.shutdown computed the time remaining after
joining the ticker thread and passed it as `timeout=`. Every
MetricExporter.shutdown is declared as
`shutdown(self, timeout_millis=30_000, **kwargs)`, so the value was absorbed
by **kwargs and discarded, and the exporter fell back to its own 30 second
default. A caller asking for a 200ms shutdown could therefore block for 30s.

The force_flush call three lines below already uses `timeout_millis=`, which
is what makes this a slip rather than a decision.

Also clamp at zero: joining the ticker thread can consume the whole budget,
which would otherwise hand the exporter a negative timeout.
Copilot AI lite review requested due to automatic review settings August 23, 2026 17:05
@dwin-gharibi
dwin-gharibi requested a review from a team as a code owner August 23, 2026 17:05

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@opentelemetry-pr-dashboard

Copy link
Copy Markdown

Pull request dashboard status

Waiting on reviewers · refreshed 2026-08-23 17:06 UTC

Review the latest changes.

Status above doesn't look right?
  • Just replied or pushed? Anything around or after the refresh time above may not be picked up yet — give it a few minutes.
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

PeriodicExportingMetricReader discards its shutdown timeout

2 participants