diff --git a/CHANGELOG.md b/CHANGELOG.md index a7d7ea2..0af0492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,12 @@ All notable changes to this project will be documented in this file. As this feature is mutually exclusive with `alpha` and `binary-pixel-sync`, `--all-features` will now fail to compile. Please choose the required features explicitly instead. +### Fixed + +- Let breakwater exit as soon as a sink reports an error ([#95]). + [#84]: https://github.com/sbernauer/breakwater/pull/84 +[#95]: https://github.com/sbernauer/breakwater/pull/95 ## [0.22.0] - 2026-06-20 diff --git a/breakwater/src/sinks/mod.rs b/breakwater/src/sinks/mod.rs index a371a24..d88bb48 100644 --- a/breakwater/src/sinks/mod.rs +++ b/breakwater/src/sinks/mod.rs @@ -128,9 +128,14 @@ pub async fn start_sinks) -> eyre::Result<()> { - tokio::signal::ctrl_c() - .await - .context("failed to wait for ctrl + c")?; +/// Blocks until either the user requests a shutdown via Ctrl+C, or one of the sinks signals +/// termination (e.g. because it crashed). Afterwards all remaining sinks are told to terminate. +async fn wait_for_shutdown( + terminate_signal_tx: broadcast::Sender<()>, + mut terminate_signal_rx: broadcast::Receiver<()>, +) -> eyre::Result<()> { + tokio::select! { + result = tokio::signal::ctrl_c() => { + result.context("failed to wait for ctrl + c")?; + } + // A sink signalled termination, e.g. because it crashed. + _ = terminate_signal_rx.recv() => {} + } - terminate_signal_tx - .send(()) - .context("failed to signal termination")?; + // Tell all remaining sinks to terminate. Best-effort: this fails if all other receivers are + // already gone (e.g. the only sink crashed and dropped its receiver), which is fine here. + let _ = terminate_signal_tx.send(()); Ok(()) }