(
mut sync_id: Option<String>,
sink: S,
mut to_writer_rx: mpsc::Receiver<ToWriter<M>>,
init: Option<M>,
finish: Option<M>,
wip_limit: usize,
metrics: Metrics,
)
| 322 | |
| 323 | #[instrument(skip_all, fields(sync_id))] |
| 324 | async fn write<M, S>( |
| 325 | mut sync_id: Option<String>, |
| 326 | sink: S, |
| 327 | mut to_writer_rx: mpsc::Receiver<ToWriter<M>>, |
| 328 | init: Option<M>, |
| 329 | finish: Option<M>, |
| 330 | wip_limit: usize, |
| 331 | metrics: Metrics, |
| 332 | ) -> Result<()> |
| 333 | where |
| 334 | S: Sink<ReconMessage<M>, Error = anyhow::Error>, |
| 335 | MessageLabels: for<'a> From<&'a M>, |
| 336 | M: std::fmt::Debug, |
| 337 | { |
| 338 | if let Some(sync_id) = &sync_id { |
| 339 | // Record sync_id on the tracing span |
| 340 | tracing::Span::current().record("sync_id", sync_id); |
| 341 | } |
| 342 | pin_mut!(sink); |
| 343 | |
| 344 | // Use a stack so we get depth first traversal |
| 345 | let mut message_stack = Vec::new(); |
| 346 | // Track in progress |
| 347 | let mut in_progress = 0; |
| 348 | |
| 349 | if let Some(init) = init { |
| 350 | trace!(?init, "sending init"); |
| 351 | metrics.record(&MessageSent(&init)); |
| 352 | sink.send(ReconMessage::new(sync_id.clone(), init)).await?; |
| 353 | } |
| 354 | |
| 355 | // Write messages to the remote until there are no more messages to send. |
| 356 | while let Some(action) = to_writer_rx.recv().await { |
| 357 | metrics.record(&ProtocolWriteLoop); |
| 358 | match action { |
| 359 | ToWriter::SyncId(remote_sync_id) => { |
| 360 | // Record sync_id on the tracing span |
| 361 | tracing::Span::current().record("sync_id", &remote_sync_id); |
| 362 | sync_id = Some(remote_sync_id); |
| 363 | } |
| 364 | ToWriter::SendAll(messages) => { |
| 365 | sink.send_all(&mut messages.map(|msg| { |
| 366 | msg.map(|message| { |
| 367 | metrics.record(&MessageSent(&message)); |
| 368 | trace!(?message, "sending message"); |
| 369 | ReconMessage::new(sync_id.clone(), message) |
| 370 | }) |
| 371 | })) |
| 372 | .await?; |
| 373 | } |
| 374 | ToWriter::WIPCompleted(count) => { |
| 375 | in_progress -= count; |
| 376 | } |
| 377 | ToWriter::SendWIPLimited(mut messages) => { |
| 378 | // Send all message that fit within the work in progress limit. |
| 379 | if in_progress < wip_limit { |
| 380 | let capacity = wip_limit - in_progress; |
| 381 | let mut sent = false; |
no test coverage detected