Skip to content

Commit a843435

Browse files
graphcarefulpront
andauthored
fix(topology): Fix for issue causing stalling on shutdown for sinks configured w/ disk buffers (#24949)
* fix(buffers): prevent reload stall when disk buffer config changes - Changing a disk buffer's configuration (e.g. `max_size`) during a live config reload would stall indefinitely or fail with a `buffer.lock` error. This was caused by two issues: 1. The sink's detach trigger was only cancelled for buffer-reuse cases, so sinks with changed disk buffer configs never had their input stream terminated — disk buffer readers do not return `None` when the writer disconnects, causing the old sink task to hang forever. 2. The source output pump only processed fanout control messages (Remove/Pause) during active sends, so idle sources would never drop their `BufferSender` clone, keeping the `Arc<Ledger>` file lock alive even after the sink task completed. - Cancel the detach trigger for changed disk buffer sinks so the old sink task can complete. - Make the source output pump `select!` on both events and fanout control messages, so Remove/Pause is processed promptly even when the source is idle. - Add a retry loop (30s timeout) when acquiring the disk buffer lock to handle the small race window between the sink task completing and the fanout releasing the writer. - Add `BufferConfig::has_disk_stage()` helper for identifying disk buffer configurations. * Add unit tests for reload when disk buffer config modified * Add changelog fragment * Integration test exercising full disk buffer path w/ s3 sink - This test sets up a pipeline that sends using the s3 sinks with disk buffers enabled. - Data is sent through the disk buffer before and after configuration reload. * Clean-up changelog fragment * Fix spelling issues * Fix merge error and cleanup use of config() - Make consistent use of the config() method in all tests within this file * Simplify set of control_channel_open status * Remove unnecessary mutable modifiers * Prefer tempDir to just writing to /tmp --------- Co-authored-by: Pavlos Rontidis <pavlos.rontidis@gmail.com>
1 parent 156b832 commit a843435

7 files changed

Lines changed: 396 additions & 111 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Fixed issue during in place reload of a sink with a disk buffer configured, where
2+
the component would stall for batch.timeout_sec before gracefully reloading.
3+
This fix also resolves issues Vector had where it would ignore SIGINT during
4+
cases where the pipeline stall had occurred.
5+
6+
authors: graphcareful

lib/vector-buffers/src/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,13 @@ impl Default for BufferConfig {
371371
}
372372

373373
impl BufferConfig {
374+
/// Returns true if any stage in this buffer configuration uses disk-based storage.
375+
pub fn has_disk_stage(&self) -> bool {
376+
self.stages()
377+
.iter()
378+
.any(|stage| matches!(stage, BufferType::DiskV2 { .. }))
379+
}
380+
374381
/// Gets all of the configured stages for this buffer.
375382
pub fn stages(&self) -> &[BufferType] {
376383
match self {

lib/vector-core/src/fanout.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,20 @@ impl Fanout {
108108
}
109109
}
110110

111+
/// Waits for the next control message and applies it.
112+
///
113+
/// Returns `true` if a message was processed, `false` if the control
114+
/// channel was closed.
115+
pub async fn recv_control_message(&mut self) -> bool {
116+
match self.control_channel.recv().await {
117+
Some(msg) => {
118+
self.apply_control_message(msg);
119+
true
120+
}
121+
None => false,
122+
}
123+
}
124+
111125
/// Apply a control message directly against this instance.
112126
///
113127
/// This method should not be used if there is an active `SendGroup` being processed.

0 commit comments

Comments
 (0)