Skip to content

chore(common): unify multiple shutdown synchronization types#1856

Merged
tobz merged 1 commit into
mainfrom
tobz/shutdown-primitives-cleanup
Jun 12, 2026
Merged

chore(common): unify multiple shutdown synchronization types#1856
tobz merged 1 commit into
mainfrom
tobz/shutdown-primitives-cleanup

Conversation

@tobz

@tobz tobz commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

This PR unifies the various shutdown synchronization types across multiple crates into a single pair of types in saluki-common.

Prior to this PR, we had five distinct shutdown types/pairs of types:

  1. DynamicShutdownCoordinator/DynamicShutdownHandle: allowed for registering shutdown handles dynamically
  2. ComponentShutdownCoordinator/ComponentShutdownHandle: basically DynamicShutdownCoordinator with a different name (my brain wasn't firing on all cylinders when I wrote this, clearly)
  3. ShutdownHandle/ProcessShutdown: a paired shutdown trigger (like a oneshot sender/receiver pair) specifically for use in saluki_core::runtime
  4. ShutdownTrigger/ShutdownHandle: a paired shutdown trigger added to saluki-common for general use where needed
  5. ShutdownHandle, exposed for use with HttpServer to trigger shutdown

Conceptually, these are all very similar:

  • 1 and 2 are basically identical: support registering multiple shutdown handles, then triggering them all at once... potentially waiting for them to complete their shutdown
  • 3 and 4 are also basically identical, and they're a subset of 1 and 2: a trigger and a handle, except only one handle is ever registered
  • 5 is just one half of the pair in 3 and 4

So I decided to unify things. In this PR, I've introduced a new pair of types for driving the sender/receiver sides of the equation: ShutdownCoordinator and ShutdownHandle. All instances of the previous five shutdown types have been replaced with these new types, fully unifying how we handle shutdown triggering/propagation. In no particular order:

  • ShutdownCoordinator supports multiple handles being registered
  • ShutdownCoordinator does a non-blocking shutdown trigger on drop, ensuring shutdown isn't missed when we hit errors/panics and don't reach the happy path shutdown call
  • ShutdownCoordinator supports both a blocking and non-blocking shutdown call: the blocking call (insofar as it waits, not that it's literally synchronous code) will wait until all shutdown handles have been dropped before returning
  • ShutdownHandle supports both synchronous and asynchronous code by exposing a method for synchronous code to check if shutdown has been triggered, while also being usable as a Future that resolves when shutdown is triggered
  • ShutdownHandle also exhibits fused/latching behavior in its Future implementation, easing potential bugs arising from misuse (re-polling resolved futures is generally bad)
  • ShutdownHandle also exposes a noop builder to allow creating handles that do nothing such that callers can pass a ShutdownHandle value to satisfy the required arguments for a method/type

Change Type

  • Bug fix
  • New feature
  • Non-functional (chore, refactoring, docs)
  • Performance

How did you test this PR?

Existing suite of tests -- unit, integration, correctness -- and a whole slew of new unit tests for the shutdown types.

References

DADP-2

@tobz tobz requested a review from a team as a code owner June 11, 2026 16:25
@dd-octo-sts dd-octo-sts Bot added area/core Core functionality, event model, etc. area/io General I/O and networking. area/config Configuration. area/components Sources, transforms, and destinations. source/dogstatsd DogStatsD source. destination/prometheus Prometheus Scrape destination. area/observability Internal observability of ADP and Saluki. source/heartbeat Heartbeat source. otlp/logs OTLP logs (OTeL, open-telemetry) source/otlp OTLP source. labels Jun 11, 2026
@datadog-prod-us1-4

This comment has been minimized.

@tobz tobz added the type/chore Updates to dependencies or general "administrative" tasks necessary to maintain the codebase/repo. label Jun 11, 2026
@pr-commenter

pr-commenter Bot commented Jun 11, 2026

Copy link
Copy Markdown

Regression Detector (Agent Data Plane)

Run ID: 241134ff-25d4-4242-b392-b505987a1218
Baseline: 559d98c2 · Comparison: b5a4d0d9 · diff

Optimization Goals: ✅ No significant changes detected

Fine details of change detection per experiment (35)

Experiments configured erratic: true are tagged (ignored) and skipped when determining which experiments regressed or improved. Experiments which are detected as erratic at runtime are tagged (erratic) to flag that the run's sample dispersion was high, but their regression / improvement signal still counts.

experiment goal Δ mean % links
otlp_ingest_traces_5mb_cpu (erratic) cpu ⚪ +2.31 metrics profiles logs
dsd_uds_1mb_3k_contexts_cpu (erratic) cpu ⚪ +2.28 metrics profiles logs
dsd_uds_10mb_3k_contexts_cpu (erratic) cpu ⚪ +2.25 metrics profiles logs
otlp_ingest_metrics_5mb_cpu (erratic) cpu ⚪ +1.92 metrics profiles logs
otlp_ingest_traces_ottl_transform_5mb_cpu (erratic) cpu ⚪ +1.77 metrics profiles logs
otlp_ingest_metrics_5mb_memory memory ⚪ +1.17 metrics profiles logs
quality_gates_rss_dsd_heavy memory ⚪ +0.74 metrics profiles logs
quality_gates_rss_idle memory ⚪ +0.70 metrics profiles logs
dsd_uds_10mb_3k_contexts_memory memory ⚪ +0.65 metrics profiles logs
quality_gates_rss_dsd_low memory ⚪ +0.58 metrics profiles logs
otlp_ingest_traces_5mb_memory memory ⚪ +0.39 metrics profiles logs
dsd_uds_500mb_3k_contexts_memory memory ⚪ +0.21 metrics profiles logs
otlp_ingest_traces_ottl_filtering_5mb_memory memory ⚪ +0.21 metrics profiles logs
dsd_uds_1mb_3k_contexts_memory memory ⚪ +0.19 metrics profiles logs
dsd_uds_500mb_3k_contexts_cpu (erratic) cpu ⚪ +0.16 metrics profiles logs
dsd_uds_512kb_3k_contexts_memory memory ⚪ +0.11 metrics profiles logs
quality_gates_rss_dsd_medium memory ⚪ +0.11 metrics profiles logs
quality_gates_rss_dsd_ultraheavy memory ⚪ +0.11 metrics profiles logs
otlp_ingest_traces_5mb_throughput throughput ⚪ -0.05 metrics profiles logs
otlp_ingest_traces_ottl_transform_5mb_memory memory ⚪ +0.04 metrics profiles logs
otlp_ingest_logs_5mb_throughput (ignored) throughput ⚪ -0.01 metrics profiles logs
dsd_uds_1mb_3k_contexts_throughput throughput ⚪ -0.00 metrics profiles logs
dsd_uds_512kb_3k_contexts_throughput throughput ⚪ -0.00 metrics profiles logs
dsd_uds_10mb_3k_contexts_throughput throughput ⚪ +0.01 metrics profiles logs
dsd_uds_100mb_3k_contexts_throughput throughput ⚪ +0.01 metrics profiles logs
otlp_ingest_metrics_5mb_throughput throughput ⚪ +0.04 metrics profiles logs
otlp_ingest_traces_ottl_filtering_5mb_cpu (erratic) cpu ⚪ -0.05 metrics profiles logs
otlp_ingest_traces_ottl_filtering_5mb_throughput throughput ⚪ +0.07 metrics profiles logs
dsd_uds_100mb_3k_contexts_memory memory ⚪ -0.07 metrics profiles logs
otlp_ingest_logs_5mb_memory (ignored) memory ⚪ -0.61 metrics profiles logs
dsd_uds_500mb_3k_contexts_throughput throughput ⚪ +0.88 metrics profiles logs
otlp_ingest_traces_ottl_transform_5mb_throughput throughput ⚪ +0.89 metrics profiles logs
otlp_ingest_logs_5mb_cpu (ignored) cpu ⚪ -1.76 metrics profiles logs
dsd_uds_100mb_3k_contexts_cpu (erratic) cpu ⚪ -2.08 metrics profiles logs
dsd_uds_512kb_3k_contexts_cpu (erratic) cpu 🟢 -10.44 metrics profiles logs
Bounds Checks: ✅ Passed (5)
experiment check replicates observed links
quality_gates_rss_dsd_heavy memory_usage 10/10 ✅ 134 MiB ≤ 140 MiB metrics profiles logs
quality_gates_rss_dsd_low memory_usage 10/10 ✅ 42.3 MiB ≤ 50 MiB metrics profiles logs
quality_gates_rss_dsd_medium memory_usage 10/10 ✅ 64.4 MiB ≤ 75 MiB metrics profiles logs
quality_gates_rss_dsd_ultraheavy memory_usage 10/10 ✅ 191 MiB ≤ 200 MiB metrics profiles logs
quality_gates_rss_idle memory_usage 10/10 ✅ 28.1 MiB ≤ 40 MiB metrics profiles logs
Explanation

A change is flagged as a regression when |Δ mean %| > 5.00% in the regressing direction for its optimization goal AND SMP marks the experiment as a regression (is_regression: true). Improvements use the matching criteria for the improving direction. Experiments configured erratic: true (tagged (ignored)) are skipped outright; experiments detected as erratic at runtime (tagged (erratic)) still count, since that flag describes sample dispersion rather than directional certainty. The Δ mean % cell is colored accordingly: 🟢 = improvement, 🔴 = regression, ⚪ = neutral. Reduction in CPU or memory is an improvement; reduction in ingress throughput is a regression.

@webern webern 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.

Nice.

@tobz tobz force-pushed the tobz/shutdown-primitives-cleanup branch from c19243d to b5a4d0d Compare June 11, 2026 19:38
@pr-commenter

pr-commenter Bot commented Jun 11, 2026

Copy link
Copy Markdown

Binary Size Analysis (Agent Data Plane)

Baseline: 559d98c · Comparison: b5a4d0d · diff
Analysis Configuration: stripped binaries · Pass/Fail Threshold: +5%
Sizes: 39.85 MiB (baseline) vs 40.14 MiB (comparison)
Size Change: +298.97 KiB (+0.73%)

✅ Binary size difference within threshold

Changes by Module
Module File Size Symbols
figment +148.93 KiB 646
tokio +59.81 KiB 4436
otlp_protos::otlp_include::opentelemetry +44.74 KiB 173
prost -43.34 KiB 472
core +28.03 KiB 14628
[sections] +17.46 KiB 7
tonic_prost +17.04 KiB 75
anon.ed27542e3dc65b9153e45118ad79a0d2.3.llvm.3582567727113537903 +16.87 KiB 1
axum +16.85 KiB 521
anon.71c1f068847d886324162068124709c1.350.llvm.9379758517637157945 -16.78 KiB 1
saluki_components::transforms::dogstatsd_mapper -16.02 KiB 16
saluki_common::cache::CacheBuilder<K,V,W,H> +15.60 KiB 6
saluki_components::common::datadog -14.33 KiB 506
hashbrown -11.32 KiB 1386
saluki_core::observability::metrics -10.90 KiB 85
saluki_components::sources::otlp -10.68 KiB 225
agent_data_plane::cli::run -10.18 KiB 108
tokio_util -9.81 KiB 102
agent_data_plane::internal::env +9.79 KiB 198
anon.f6e07010805ed4b818f41e3f715e6037.677.llvm.7714834860777622366 +8.75 KiB 1
Detailed Symbol Changes
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +1.3%  +311Ki  +1.4%  +259Ki    [52387 Others]
  [NEW] +52.0Ki  [NEW] +51.8Ki    saluki_components::common::datadog::io::run_endpoint_io_loop::_{{closure}}::h43c7a2111ec7cbee
  [NEW] +38.8Ki  [NEW] +38.7Ki    agent_data_plane::cli::run::handle_run_command::_{{closure}}::hd298fe23ce1abc05
  [NEW] +38.7Ki  [NEW] +38.5Ki    _<saluki_components::forwarders::otlp::OtlpForwarder as saluki_core::components::forwarders::Forwarder>::run::_{{closure}}::hc4a5adc58469edce
  [NEW] +35.3Ki  [NEW] +35.1Ki    _<saluki_components::transforms::aggregate::Aggregate as saluki_core::components::transforms::Transform>::run::_{{closure}}::h686a5d390ceb2100
  [NEW] +30.2Ki  [NEW] +30.1Ki    agent_data_plane::cli::dogstatsd::handle_dogstatsd_command::_{{closure}}::h819699791c1100ac
  [NEW] +28.5Ki  [NEW] +28.4Ki    saluki_components::sources::otlp::metrics::translator::OtlpMetricsTranslator::translate_metrics::h5eb8cd431c403b41
  [NEW] +26.8Ki  [NEW] +26.7Ki    saluki_components::sources::dogstatsd::drive_stream::_{{closure}}::ha17347e186c106b9
  [NEW] +25.5Ki  [NEW] +25.3Ki    agent_data_plane::internal::remote_agent::run_remote_agent_registration_loop::_{{closure}}::h45a1a8fabe916ad7
  [NEW] +25.0Ki  [NEW] +24.8Ki    core::ptr::drop_in_place<agent_data_plane::cli::run::handle_run_command::{{closure}}>::h8159e8a81b0b36fd
  [NEW] +24.5Ki  [NEW] +24.4Ki    h2::proto::connection::DynConnection<B>::recv_frame::h2441906561c61178
  [DEL] -24.2Ki  [DEL] -24.0Ki    core::ptr::drop_in_place<agent_data_plane::cli::run::handle_run_command::{{closure}}>::h1dd4120ec3ec6d5c
  [DEL] -24.6Ki  [DEL] -24.4Ki    agent_data_plane::internal::remote_agent::run_remote_agent_registration_loop::_{{closure}}::h6ae2b4ba5ed1f5ab
  [DEL] -25.9Ki  [DEL] -25.8Ki    saluki_components::sources::dogstatsd::drive_stream::_{{closure}}::h499b3cdd6d6beb82
  [DEL] -28.5Ki  [DEL] -28.4Ki    saluki_components::sources::otlp::metrics::translator::OtlpMetricsTranslator::translate_metrics::haefb58c0f02234a8
  [DEL] -30.1Ki  [DEL] -30.0Ki    agent_data_plane::cli::dogstatsd::handle_dogstatsd_command::_{{closure}}::h11e8854c933a8098
  [DEL] -31.6Ki  [DEL] -31.5Ki    agent_data_plane::internal::env::workload::RemoteAgentWorkloadProvider::from_configuration::_{{closure}}::h4e7da8d1ac8d0e9b
  [DEL] -33.5Ki  [DEL] -33.3Ki    _<saluki_components::transforms::aggregate::Aggregate as saluki_core::components::transforms::Transform>::run::_{{closure}}::h192ba0b55f6674d3
  [DEL] -35.3Ki  [DEL] -35.1Ki    _<saluki_components::forwarders::otlp::OtlpForwarder as saluki_core::components::forwarders::Forwarder>::run::_{{closure}}::hab94aa8347dcd327
  [DEL] -49.8Ki  [DEL] -49.7Ki    agent_data_plane::cli::run::handle_run_command::_{{closure}}::h2f426cd320078741
  [DEL] -54.3Ki  [DEL] -54.1Ki    saluki_components::common::datadog::io::run_endpoint_io_loop::_{{closure}}::h737255a90400e679
  +0.7%  +298Ki  +0.8%  +247Ki    TOTAL

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

Labels

area/components Sources, transforms, and destinations. area/config Configuration. area/core Core functionality, event model, etc. area/io General I/O and networking. area/observability Internal observability of ADP and Saluki. destination/prometheus Prometheus Scrape destination. otlp/logs OTLP logs (OTeL, open-telemetry) source/dogstatsd DogStatsD source. source/heartbeat Heartbeat source. source/otlp OTLP source. type/chore Updates to dependencies or general "administrative" tasks necessary to maintain the codebase/repo.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants