servers/prom_remote_write/
mod.rs1pub mod decode;
21pub(crate) mod row_builder;
22pub(crate) mod types;
23#[cfg(any(test, feature = "testing"))]
24pub mod v2;
25#[cfg(not(any(test, feature = "testing")))]
26pub(crate) mod v2;
27pub mod validation;
28
29use bytes::Bytes;
30use common_error::ext::BoxedError;
31use common_memory_manager::MemoryGuard;
32use lazy_static::lazy_static;
33use object_pool::Pool;
34use snafu::{IntoError, ResultExt};
35
36use crate::error;
37use crate::prom_remote_write::decode::{PromSeriesProcessor, PromWriteRequest};
38use crate::prom_remote_write::row_builder::TablesBuilder;
39use crate::prom_remote_write::validation::PromValidationMode;
40use crate::prom_store::{
41 ChargedBuffer, MAX_DECOMPRESSED_REQUEST_SIZE, snappy_decompress_limited,
42 zstd_decompress_limited,
43};
44use crate::request_memory_limiter::ServerMemoryLimiter;
45use crate::request_memory_metrics::RequestMemoryMetrics;
46
47pub const REMOTE_WRITE_V1_VERSION: &str = "1.0";
50pub const REMOTE_WRITE_V2_VERSION: &str = "2.0";
51
52lazy_static! {
53 static ref PROM_WRITE_REQUEST_POOL: Pool<PromWriteRequest<'static>> =
54 Pool::new(256, PromWriteRequest::default);
55}
56
57pub(crate) async fn decompress_remote_write_body(
71 is_zstd: bool,
72 body: &[u8],
73 limiter: &ServerMemoryLimiter,
74 body_reserved_bytes: u64,
75) -> crate::error::Result<ChargedBuffer> {
76 let decompress = |is_zstd: bool| async move {
77 if is_zstd {
78 zstd_decompress_limited(
79 body,
80 MAX_DECOMPRESSED_REQUEST_SIZE,
81 limiter,
82 body_reserved_bytes,
83 )
84 .await
85 } else {
86 snappy_decompress_limited(
87 body,
88 MAX_DECOMPRESSED_REQUEST_SIZE,
89 limiter,
90 body_reserved_bytes,
91 )
92 .await
93 }
94 };
95
96 match decompress(is_zstd).await {
97 Ok(buf) => Ok(buf),
98 Err(e) => {
99 if matches!(
100 e,
101 crate::error::Error::DecompressSnappyPromRemoteRequest { .. }
102 | crate::error::Error::DecompressZstdPromRemoteRequest { .. }
103 ) {
104 decompress(!is_zstd).await
105 } else {
106 Err(e)
107 }
108 }
109 }
110}
111
112pub async fn decode_remote_write_request(
113 is_zstd: bool,
114 body: Bytes,
115 prom_validation_mode: PromValidationMode,
116 processor: &mut PromSeriesProcessor,
117 limiter: &ServerMemoryLimiter,
118) -> crate::error::Result<(
119 TablesBuilder<'static>,
120 Vec<MemoryGuard<RequestMemoryMetrics>>,
121)> {
122 let _timer = crate::metrics::METRIC_HTTP_PROM_STORE_CODEC_ELAPSED
123 .with_label_values(&["decode", REMOTE_WRITE_V1_VERSION])
124 .start_timer();
125
126 let buf = decompress_remote_write_body(is_zstd, &body[..], limiter, 0).await?;
130 drop(body);
132 let (data, guards) = buf.into_parts();
133 let mut request = PROM_WRITE_REQUEST_POOL.pull(PromWriteRequest::default);
134
135 request
136 .decode(data, prom_validation_mode, processor)
137 .context(error::DecodePromRemoteRequestSnafu)?;
138 let tables = std::mem::take(&mut request.table_data);
139 Ok((tables, guards))
140}
141
142pub(crate) fn map_memory_acquire_timeout(error: error::Error) -> error::Error {
144 match error {
145 error::Error::MemoryLimitExceeded {
146 source: source @ common_memory_manager::Error::MemoryAcquireTimeout { .. },
147 ..
148 } => error::OtherSnafu.into_error(BoxedError::new(source)),
149 error => error,
150 }
151}