Skip to content

[SDK] Fix MetricReader post shutdown handling - #4548

Merged
marcalff merged 10 commits into
open-telemetry:mainfrom
denizariyan:fix/metric-reader-shutdown
Sep 13, 2026
Merged

[SDK] Fix MetricReader post shutdown handling#4548
marcalff merged 10 commits into
open-telemetry:mainfrom
denizariyan:fix/metric-reader-shutdown

Conversation

@denizariyan

@denizariyan denizariyan commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Fixes #4536

Changes

  • Run on shutdown method only once
  • Also fix a similar "warn but don't actually do what you say you do" issue on force flush in metric reader

For significant contributions please make sure you have completed the following items:

  • CHANGELOG.md updated for non-trivial changes
  • Unit tests have been added
  • Changes in public API reviewed

@denizariyan
denizariyan marked this pull request as ready for review September 9, 2026 16:27
@denizariyan
denizariyan requested a review from a team as a code owner September 9, 2026 16:27
@denizariyan denizariyan changed the title [SDK] Fix MetricReader Shutdown invoking OnShutDown() multiple times [SDK] Fix MetricReader Shutdown invoking OnShutDown multiple times Sep 9, 2026
@denizariyan denizariyan changed the title [SDK] Fix MetricReader Shutdown invoking OnShutDown multiple times [SDK] Fix MetricReader post shutdown handling Sep 9, 2026
@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.47%. Comparing base (e0e0458) to head (7e75347).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #4548      +/-   ##
==========================================
+ Coverage   86.45%   86.47%   +0.02%     
==========================================
  Files         525      525              
  Lines       20450    20453       +3     
==========================================
+ Hits        17679    17685       +6     
+ Misses       2771     2768       -3     
Files with missing lines Coverage Δ
.../include/opentelemetry/sdk/metrics/metric_reader.h 100.00% <ø> (ø)
sdk/src/metrics/metric_reader.cc 91.38% <100.00%> (+5.93%) ⬆️

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mateenali66

Copy link
Copy Markdown
Member

the CAS fixes the sequential double invoke, but a concurrent second caller now gets true back before the first has finished OnShutDown().

built this branch's metric_reader.cc against a reader whose OnShutDown() sleeps 300ms, thread B running 50ms behind thread A:

                            main    this PR   +mutex
second Shutdown() blocked   304ms   0ms       249ms
OnShutDown done by then     yes     NO        yes
OnShutDown invocations      2       1         1

BatchSpanProcessor::InternalShutdown avoids this by taking shutdown_m before the exchange (batch_span_processor.cc:383-384), so the second caller waits and then sees already_shutdown. the third column is that idiom in MetricReader.

ConcurrentShutdownIsInvokedOnce cannot catch it, since OnShutDown returns immediately there. it matters because ~PeriodicExportingMetricReader() skips Shutdown() when IsShutdown() is true (periodic_exporting_metric_reader.cc:77), so a caller acting on the early true can tear down mid join().

mutex, or document Shutdown() as not concurrency safe and keep the CAS?

Comment thread sdk/include/opentelemetry/sdk/metrics/metric_reader.h Outdated
Comment thread sdk/test/metrics/metric_reader_test.cc Outdated
@dbarker dbarker added the pr:please-review This PR is ready for review label Sep 11, 2026
@denizariyan

Copy link
Copy Markdown
Contributor Author

the CAS fixes the sequential double invoke, but a concurrent second caller now gets true back before the first has finished OnShutDown().

built this branch's metric_reader.cc against a reader whose OnShutDown() sleeps 300ms, thread B running 50ms behind thread A:

                            main    this PR   +mutex
second Shutdown() blocked   304ms   0ms       249ms
OnShutDown done by then     yes     NO        yes
OnShutDown invocations      2       1         1

BatchSpanProcessor::InternalShutdown avoids this by taking shutdown_m before the exchange (batch_span_processor.cc:383-384), so the second caller waits and then sees already_shutdown. the third column is that idiom in MetricReader.

ConcurrentShutdownIsInvokedOnce cannot catch it, since OnShutDown returns immediately there. it matters because ~PeriodicExportingMetricReader() skips Shutdown() when IsShutdown() is true (periodic_exporting_metric_reader.cc:77), so a caller acting on the early true can tear down mid join().

mutex, or document Shutdown() as not concurrency safe and keep the CAS?

Thanks, I agree I think serializing the concurrent calls here is the less surprising implementation. It also matches what BSP does.

I changed it the impl to serialize each call to shutdown. This might be something we need to revisit when implementing timeout handling but I think is the better choice for now

@marcalff
marcalff merged commit 8e61017 into open-telemetry:main Sep 13, 2026
77 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:please-review This PR is ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] MetricReader::Shutdown() logs "cannot invoke shutdown twice" but calls OnShutDown() again anyway

5 participants