aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/stats.rs4
-rw-r--r--src/api/stats/prometheus.rs8
-rw-r--r--src/document/mod.rs10
-rw-r--r--src/swarm/stats.rs14
4 files changed, 33 insertions, 3 deletions
diff --git a/src/api/stats.rs b/src/api/stats.rs
index 90b4fc2..37a7447 100644
--- a/src/api/stats.rs
+++ b/src/api/stats.rs
@@ -101,6 +101,9 @@ struct DocumentStats {
saved_bytes_secs_ago: Option<u64>,
/// How long the last measurement took (copy and save), in milliseconds.
saved_bytes_took_ms: Option<u64>,
+ /// Writers (Automerge actors: a node's run each) with changes in the document,
+ /// counted with `saved_bytes`; absent until first counted.
+ writers: Option<usize>,
/// How long takers of the document's lock waited for it, since start: the node's
/// work on the one document queues there.
lock_wait: crate::document::lock::LockWaits,
@@ -360,6 +363,7 @@ pub(crate) async fn collect(state: &AppState, list: &PeerListResponse) -> StatsR
saved_bytes: saved.map(|s| s.bytes),
saved_bytes_secs_ago: saved.map(|s| s.at.elapsed().as_secs()),
saved_bytes_took_ms: saved.map(|s| s.took.as_millis() as u64),
+ writers: saved.and_then(|s| s.writers),
lock_wait: state.doc.waits(),
},
catch_up: CatchUpStats {
diff --git a/src/api/stats/prometheus.rs b/src/api/stats/prometheus.rs
index 0d79d2c..ca3f1af 100644
--- a/src/api/stats/prometheus.rs
+++ b/src/api/stats/prometheus.rs
@@ -460,6 +460,14 @@ pub(super) fn render(stats: &StatsResponse, list: &PeerListResponse) -> String {
"Most heads after applying a sync message, since start.",
document.max_heads as f64,
);
+ if let Some(writers) = document.writers {
+ out.single(
+ "document_writers",
+ "gauge",
+ "Writers (Automerge actors, a node's run each) with changes in the document; counted in the background.",
+ writers as f64,
+ );
+ }
if let Some(bytes) = document.saved_bytes {
out.single(
"document_saved_bytes",
diff --git a/src/document/mod.rs b/src/document/mod.rs
index c183537..a546d63 100644
--- a/src/document/mod.rs
+++ b/src/document/mod.rs
@@ -13,6 +13,16 @@ pub(crate) use automerge::{
ScalarValue,
};
+/// How many writers (actors) `doc`'s changes have: from the changes' metadata, in
+/// time proportional to the document.
+pub(crate) fn writers(doc: &Document) -> usize {
+ doc.get_changes_meta(&[])
+ .into_iter()
+ .map(|meta| meta.actor.into_owned())
+ .collect::<std::collections::HashSet<_>>()
+ .len()
+}
+
/// The whole document as bytes, as the engine saves it: a backup, the document
/// file's full save, the size a joining node downloads.
pub(crate) fn save(doc: &Document) -> Vec<u8> {
diff --git a/src/swarm/stats.rs b/src/swarm/stats.rs
index ed12888..3665b5a 100644
--- a/src/swarm/stats.rs
+++ b/src/swarm/stats.rs
@@ -99,12 +99,16 @@ impl Propagation {
}
/// The document's size as saved (compressed), when it was measured and how long that
-/// took (copy and save).
+/// took (copy and save), and how many writers (Automerge actors) its changes have.
#[derive(Debug, Clone, Copy)]
pub(crate) struct SavedSize {
pub(crate) bytes: u64,
pub(crate) at: Instant,
pub(crate) took: Duration,
+ /// Writers with changes in the document, counted with the measurement: a node's
+ /// run each, so many a transfer of the whole history carries a signature for. None
+ /// where only the size was measured (an export).
+ pub(crate) writers: Option<usize>,
}
/// Passing changes on (`swarm::relay`), since start.
@@ -434,10 +438,12 @@ impl NodeStats {
/// measurement for free.
pub(crate) fn saved_size_measured(&self, bytes: u64, took: Duration, version: (u64, Epoch)) {
let mut inner = self.lock();
+ let writers = inner.saved_size.and_then(|saved| saved.writers);
inner.saved_size = Some(SavedSize {
bytes,
at: Instant::now(),
took,
+ writers,
});
inner.measured_version = Some(version);
}
@@ -494,11 +500,12 @@ pub(crate) fn measure_saved_size(state: &AppState) {
// Both steps take time proportional to the document: off the async threads.
let measured = match tokio::task::spawn_blocking(move || {
let copy = doc.blocking_read().doc.clone();
- crate::document::save(&copy).len() as u64
+ let writers = crate::document::writers(&copy);
+ (crate::document::save(&copy).len() as u64, writers)
})
.await
{
- Ok(bytes) => {
+ Ok((bytes, writers)) => {
let took = start.elapsed();
debug!(
bytes,
@@ -510,6 +517,7 @@ pub(crate) fn measure_saved_size(state: &AppState) {
bytes,
at: Instant::now(),
took,
+ writers: Some(writers),
},
version,
))