loro_internal/
pre_commit.rs

1use std::sync::{Arc, Mutex};
2
3use crate::{
4    change::{Change, Timestamp},
5    oplog::get_timestamp_now_txn,
6    ChangeMeta,
7};
8use loro_common::PeerID;
9
10/// The callback of the first commit from a peer.
11pub type FirstCommitFromPeerCallback =
12    Box<dyn Fn(&FirstCommitFromPeerPayload) -> bool + Send + Sync + 'static>;
13pub type PreCommitCallback = Box<dyn Fn(&PreCommitCallbackPayload) -> bool + Send + Sync + 'static>;
14
15/// The payload of the pre commit callback.
16#[derive(Debug, Clone)]
17pub struct PreCommitCallbackPayload {
18    /// The metadata of the change which will be committed.
19    pub change_meta: ChangeMeta,
20    /// The origin of the commit.
21    pub origin: String,
22    /// The modifier of the change. You can modify the change in the callback.
23    pub modifier: ChangeModifier,
24}
25
26/// The payload of the first commit from a peer callback.
27#[derive(Debug, Clone)]
28pub struct FirstCommitFromPeerPayload {
29    /// The peer id of the first commit.
30    pub peer: PeerID,
31}
32
33#[derive(Debug, Clone, Default)]
34pub struct ChangeModifier(Arc<Mutex<ChangeModifierInner>>);
35
36#[derive(Debug, Default)]
37struct ChangeModifierInner {
38    new_msg: Option<Arc<str>>,
39    new_timestamp: Option<Timestamp>,
40}
41
42impl ChangeModifier {
43    pub fn set_message(&self, msg: &str) -> &Self {
44        self.0.lock().unwrap().new_msg = Some(Arc::from(msg));
45        self
46    }
47
48    pub fn set_timestamp(&self, timestamp: Timestamp) -> &Self {
49        self.0.lock().unwrap().new_timestamp = Some(timestamp);
50        self
51    }
52
53    pub fn set_timestamp_now(&self) -> &Self {
54        self.0.lock().unwrap().new_timestamp = Some(get_timestamp_now_txn());
55        self
56    }
57
58    pub(crate) fn modify_change(&self, change: &mut Change) {
59        let m = self.0.lock().unwrap();
60        if let Some(msg) = &m.new_msg {
61            change.commit_msg = Some(msg.clone());
62        }
63
64        if let Some(timestamp) = m.new_timestamp {
65            change.timestamp = timestamp;
66        }
67    }
68}