Skip to main content

loro_internal/
pre_commit.rs

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