Skip to main content

nodedb_types/sync/wire/
timeseries.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Timeseries ingest + definition-sync messages.
4
5use std::collections::HashMap;
6
7use serde::{Deserialize, Serialize};
8
9use crate::sync::wire::ack_status::AckStatus;
10
11/// Timeseries metric batch push (client → server, 0x40).
12#[derive(
13    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
14)]
15pub struct TimeseriesPushMsg {
16    /// Source Lite instance ID (UUID v7).
17    pub lite_id: String,
18    /// Monotonic batch ID for ACK correlation, echoed verbatim on
19    /// [`TimeseriesAckMsg::batch_id`].
20    ///
21    /// Identifies *this* batch specifically, which `seq` cannot: `applied_seq`
22    /// on the ack is a cumulative producer frontier, so it can only retire
23    /// batches at or below the frontier. A terminally rejected batch never
24    /// advances the frontier, so without this field the sender has no way to
25    /// name the one batch it must retire.
26    pub batch_id: u64,
27    /// Collection name.
28    pub collection: String,
29    /// Gorilla-encoded timestamp block.
30    pub ts_block: Vec<u8>,
31    /// Gorilla-encoded value block.
32    pub val_block: Vec<u8>,
33    /// Raw LE u64 series ID block.
34    pub series_block: Vec<u8>,
35    /// Number of samples in this batch.
36    pub sample_count: u64,
37    /// Min timestamp in this batch.
38    pub min_ts: i64,
39    /// Max timestamp in this batch.
40    pub max_ts: i64,
41    /// Per-series sync watermark: highest LSN already synced for each series.
42    /// Only samples after these watermarks are included.
43    pub watermarks: HashMap<u64, u64>,
44    /// Stable identity of the originating producer. 0 for legacy clients.
45    #[serde(default)]
46    pub producer_id: u64,
47    /// Monotonic epoch counter incremented on every producer restart.
48    #[serde(default)]
49    pub epoch: u64,
50    /// Per-stream monotonic sequence number within the epoch.
51    #[serde(default)]
52    pub seq: u64,
53}
54
55/// Timeseries push acknowledgment (server → client, 0x41).
56#[derive(
57    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
58)]
59pub struct TimeseriesAckMsg {
60    /// Collection acknowledged.
61    pub collection: String,
62    /// The [`TimeseriesPushMsg::batch_id`] this ack answers, echoed verbatim.
63    ///
64    /// Every ack path sets it, including the rejection paths that never reach
65    /// the Data Plane — a rejection the sender cannot correlate back to a batch
66    /// is a rejection it cannot act on.
67    pub batch_id: u64,
68    /// Number of samples accepted.
69    pub accepted: u64,
70    /// Number of samples rejected (duplicates, out-of-retention, etc.)
71    pub rejected: u64,
72    /// Server-assigned LSN for this batch (used as sync watermark).
73    pub lsn: u64,
74    /// Highest sequence number from this producer that has been durably applied.
75    #[serde(default)]
76    pub applied_seq: u64,
77    /// Idempotency outcome of the acknowledged message.
78    #[serde(default)]
79    pub status: AckStatus,
80}
81
82/// Definition sync message (server → client, 0x70).
83///
84/// Carries function/trigger/procedure definitions from Origin to Lite.
85/// Sent when definitions are created, modified, or dropped on Origin.
86#[derive(
87    Debug, Clone, Serialize, Deserialize, zerompk::ToMessagePack, zerompk::FromMessagePack,
88)]
89pub struct DefinitionSyncMsg {
90    /// Authenticated tenant that owns this definition.
91    pub tenant_id: u64,
92    /// Database namespace that owns this definition.
93    pub database_id: u64,
94    /// Type of definition: "function", "trigger", "procedure".
95    pub definition_type: String,
96    /// The definition name.
97    pub name: String,
98    /// Action: "put" (create/replace) or "delete" (drop).
99    pub action: String,
100    /// Serialized definition body (JSON). Empty for "delete" actions.
101    pub payload: Vec<u8>,
102}