Something went wrong. Try again.
forked from evanpurkhiser/things3-cloud
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133use std::collections::BTreeMap;
use anyhow::Result;use serde_json::json;use tracing::debug;
use crate::{ client::ThingsCloudClient, common::{printable_json, printable_plain}, wire::wire_object::WireObject,};
pub trait CloudWriter { fn commit(&mut self, changes: BTreeMap<String, WireObject>) -> Result<i64>;
fn head_index(&self) -> i64;}
pub struct LoggingCloudWriter { inner: Box<dyn CloudWriter>,}
impl LoggingCloudWriter { pub fn new(inner: Box<dyn CloudWriter>) -> Self { Self { inner } }}
impl CloudWriter for LoggingCloudWriter { fn commit(&mut self, changes: BTreeMap<String, WireObject>) -> Result<i64> { // a commit builds on the client's head // that is the synced head or the one the previous commit returned let ancestor_index = self.inner.head_index(); let uuids = changes.keys().cloned().collect::<Vec<_>>(); // the payload is serialized for the log only when that log is on let request_json = if tracing::enabled!(target: "things::cloud::commit::request", tracing::Level::DEBUG) { serde_json::to_string(&json!({ "ancestor_index": ancestor_index, "changes": &changes, })) .unwrap_or_else(|error| json!({ "error": error.to_string() }).to_string()) } else { String::new() }; debug!( target: "things::cloud::commit::request", event = "cloud.commit.request", ancestor_index, change_count = uuids.len(), uuids = ?uuids, request_json = %printable_json(&request_json), "cloud commit request" );
match self.inner.commit(changes) { Ok(head_index) => { debug!( target: "things::cloud::commit::success", event = "cloud.commit.success", ancestor_index, change_count = uuids.len(), uuids = ?uuids, head_index, "cloud commit succeeded" ); Ok(head_index) } // the command returns the error // the event is for a debug log Err(err) => { debug!( target: "things::cloud::commit::error", event = "cloud.commit.error", ancestor_index, change_count = uuids.len(), uuids = ?uuids, error = %printable_plain(&format!("{err:#}")), "cloud commit failed" ); Err(err) } } }
fn head_index(&self) -> i64 { self.inner.head_index() }}
/// commits against the history and head of the client that synchronized this run's statepub struct LiveCloudWriter { client: ThingsCloudClient,}
#[derive(Default)]pub struct DryRunCloudWriter { head_index: i64,}
impl DryRunCloudWriter { pub fn new() -> Self { Self::default() }}
impl LiveCloudWriter { pub fn new(client: ThingsCloudClient) -> Self { Self { client } }}
impl CloudWriter for LiveCloudWriter { fn commit(&mut self, changes: BTreeMap<String, WireObject>) -> Result<i64> { self.client.commit(changes) }
fn head_index(&self) -> i64 { self.client.head_index }}
impl CloudWriter for DryRunCloudWriter { fn commit(&mut self, _changes: BTreeMap<String, WireObject>) -> Result<i64> { self.head_index += 1; Ok(self.head_index) }
fn head_index(&self) -> i64 { self.head_index }}