aboutsummaryrefslogtreecommitdiffstats
path: root/src/state/mod.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-11-01 22:22:41 +0100
committertv <tv@krebsco.de>2026-11-01 22:22:41 +0100
commitb2273bc74e18201318f1e86b0f27a6a3cd874629 (patch)
tree64bb39b785553432b81ba87c6bbc59d6bc79e078 /src/state/mod.rs
parent8b5528b9d0135ec67be504c92e1740fc9a78b6e0 (diff)
record node ID and API user for every write
Diffstat (limited to 'src/state/mod.rs')
-rw-r--r--src/state/mod.rs25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/state/mod.rs b/src/state/mod.rs
index cd96aaf..85955fe 100644
--- a/src/state/mod.rs
+++ b/src/state/mod.rs
@@ -418,6 +418,20 @@ impl AppState {
T: Send + 'static,
E: From<StoreError> + Send + 'static,
{
+ self.mutate_doc_for(None, f).await
+ }
+
+ /// [`mutate_doc`](Self::mutate_doc) for `user`, who wrote through the API: the
+ /// change names them (`replica::Writer`).
+ pub(crate) async fn mutate_doc_for<T, E>(
+ &self,
+ user: Option<String>,
+ f: impl FnOnce(&mut Transaction<'_>) -> Result<T, E> + Send + 'static,
+ ) -> Result<T, E>
+ where
+ T: Send + 'static,
+ E: From<StoreError> + Send + 'static,
+ {
let state = self.clone();
tokio::task::spawn_blocking(move || {
@@ -433,15 +447,24 @@ impl AppState {
return Err(E::from(StoreError::Rejoining));
};
let mut doc = stale.write_or_recover();
+ let writer = crate::document::replica::Writer {
+ node: state.local_id(),
+ user: user.as_deref(),
+ };
return crate::document::replica::transact(
&mut doc,
state.clock.now_millis(),
+ &writer,
f,
);
}
// One API write = one change; on error, its partial writes (e.g. the old
// value deleted, the new one not written) are dropped.
- let result = replica.transact(state.clock.now_millis(), f);
+ let writer = crate::document::replica::Writer {
+ node: state.local_id(),
+ user: user.as_deref(),
+ };
+ let result = replica.transact(state.clock.now_millis(), &writer, f);
replica.refresh_heads();
result
}; // lock released before notifying