From ca3af722d00ede48e259a798ee55c9320391c13e Mon Sep 17 00:00:00 2001 From: Dennis Zhuang Date: Sun, 20 Sep 2026 14:13:01 +0800 Subject: [PATCH] revert(prom): keep the remote write v1 decode buffer until the write finishes This reverts commit 8232c5b3bb00a656031620d1b30929e604d42717. The v1 decoder fabricates `&'static [u8]` pointing into its own decode buffer (prom_remote_write/types.rs), so the compiler checks nothing about that buffer's lifetime. Holding the builder until the handler returns is what keeps the decoder safe by construction; releasing it early made that safety depend on every consumer copying out of the buffer, which holds today but nothing enforces. Document the requirement at the binding instead. Signed-off-by: Dennis Zhuang --- src/servers/src/http/prom_store.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/servers/src/http/prom_store.rs b/src/servers/src/http/prom_store.rs index b678a2e47ec..98e79bb8841 100644 --- a/src/servers/src/http/prom_store.rs +++ b/src/servers/src/http/prom_store.rs @@ -175,17 +175,15 @@ async fn remote_write_v1( processor.set_pipeline(pipeline_handler, query_ctx.clone(), pipeline_def); } - let mut decoded = - decode_remote_write_request(is_zstd, body, prom_validation_mode, &mut processor)?; + // Hold `req` until the write finishes. The v1 decoder fabricates + // `&'static [u8]` into its own decode buffer, so nothing about that + // buffer's lifetime is checked by the compiler. + let mut req = decode_remote_write_request(is_zstd, body, prom_validation_mode, &mut processor)?; - // Rows and pipeline values own their data; the decode buffer need not span downstream awaits. let req = if processor.use_pipeline { - drop(decoded); processor.exec_pipeline().await? } else { - let req = decoded.as_insert_requests(); - drop(decoded); - req + req.as_insert_requests() }; let batches = into_prom_write_batches(req, query_ctx);