MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / stream_ops

Method stream_ops

nodedb/src/control/array_sync/catchup.rs:154–220  ·  view source on GitHub ↗

Stream all ops for `array` with `hlc >= from_hlc` as batched delta frames, advancing the subscriber cursor after each batch.

(&self, session_id: &str, array: &str, from_hlc: Hlc)

Source from the content-addressed store, hash-verified

152 /// Stream all ops for `array` with `hlc >= from_hlc` as batched delta
153 /// frames, advancing the subscriber cursor after each batch.
154 fn stream_ops(&self, session_id: &str, array: &str, from_hlc: Hlc) -> crate::Result<()> {
155 // scan_from returns all ops with hlc >= from_hlc across all arrays;
156 // we filter to the target array here.
157 let ops_all = self
158 .op_log
159 .scan_from(from_hlc)
160 .map_err(|e| crate::Error::Storage {
161 engine: "array_sync".into(),
162 detail: format!("catchup_server scan_from: {e}"),
163 })?;
164
165 let mut batch_payloads: Vec<Vec<u8>> = Vec::with_capacity(BATCH_SIZE);
166 let mut last_hlc = from_hlc;
167
168 for op_result in ops_all {
169 let op = op_result.map_err(|e| crate::Error::Storage {
170 engine: "array_sync".into(),
171 detail: format!("catchup_server scan_from iter: {e}"),
172 })?;
173 if op.header.array != array {
174 continue;
175 }
176
177 match op_codec::encode_op(&op) {
178 Ok(payload) => {
179 last_hlc = op.header.hlc;
180 batch_payloads.push(payload);
181 }
182 Err(e) => {
183 warn!(
184 session = %session_id,
185 array = %array,
186 error = %e,
187 "catchup_server: encode_op failed — skipping op"
188 );
189 continue;
190 }
191 }
192
193 if batch_payloads.len() >= BATCH_SIZE {
194 let batch = ArrayDeltaBatchMsg {
195 array: array.to_owned(),
196 op_payloads: std::mem::take(&mut batch_payloads),
197 };
198 self.send_frame(session_id, SyncMessageType::ArrayDeltaBatch, &batch);
199 self.cursors.mark_sent(session_id, array, last_hlc);
200 debug!(
201 session = %session_id,
202 array = %array,
203 last_hlc = ?last_hlc,
204 "catchup_server: flushed batch"
205 );
206 }
207 }
208
209 // Flush any remaining ops.
210 if !batch_payloads.is_empty() {
211 let batch = ArrayDeltaBatchMsg {

Callers 1

serveMethod · 0.80

Calls 8

encode_opFunction · 0.85
takeFunction · 0.85
send_frameMethod · 0.80
mark_sentMethod · 0.80
scan_fromMethod · 0.45
pushMethod · 0.45
lenMethod · 0.45
is_emptyMethod · 0.45

Tested by

no test coverage detected