Skip to content

Commit 90c9fd8

Browse files
committed
docs: clarify deferred persistence terminology
1 parent 2242401 commit 90c9fd8

File tree

3 files changed

+62
-31
lines changed

3 files changed

+62
-31
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

firewood/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ rust-version.workspace = true
2424

2525
[dependencies]
2626
# Workspace dependencies
27+
aquamarine.workspace = true
2728
bytemuck_derive.workspace = true
2829
bytemuck.workspace = true
2930
coarsetime.workspace = true

firewood/src/persist_worker.rs

Lines changed: 60 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,43 +11,30 @@
1111
//! methods to send revisions for persistence, with built-in backpressure to limit
1212
//! the number of unpersisted commits.
1313
//!
14-
//! The diagram below shows how commits are handled under deferred persistence.
15-
//! The main thread updates shared state and signals the background thread via
16-
//! condition variables. Backpressure is enforced by waiting when all permits
17-
//! are exhausted.
14+
//! # Permit model
1815
//!
19-
//! Below is an example when `commit_count` is set to 10:
16+
//! Backpressure is managed through a fixed pool of **permits**, sized by `commit_count`
17+
//! (the maximum number of unpersisted commits allowed at any time).
2018
//!
21-
//! ```mermaid
22-
//! sequenceDiagram
23-
//! participant Caller
24-
//! participant Main as Main Thread
25-
//! participant BG as Background Thread
26-
//! participant Disk
19+
//! - **Commits consume permits.** Each call to [`PersistWorker::persist`] stores the
20+
//! latest committed revision and consumes one permit. If no permits remain, the
21+
//! caller blocks until the background thread releases some.
2722
//!
28-
//! loop Commits 1-4
29-
//! Caller->>Main: commit()
30-
//! Main->>Main: store latest revision, count -= 1
31-
//! Note right of BG: Waiting (count > threshold)
32-
//! end
23+
//! - **Persists release permits.** When the background thread writes a revision to disk,
24+
//! all permits consumed since the last persist are released at once, unblocking any
25+
//! waiting committers.
3326
//!
34-
//! Caller->>Main: commit() (5th)
35-
//! Main->>Main: store latest revision, count -= 1
36-
//! Main->>BG: notify persist_ready
37-
//! BG->>Disk: persist latest revision
38-
//! Note right of Disk: Sub-interval (10/2) reached
27+
//! - **A threshold triggers persistence.** The background thread wakes when the number
28+
//! of available permits drops to `persist_threshold` (equal to `commit_count / 2`,
29+
//! rounded down). It then persists the most recent revision and releases the consumed
30+
//! permits in bulk. Only the latest revision is persisted because persisting a revision
31+
//! implicitly includes the effects of all prior revisions.
3932
//!
40-
//! loop Commits 6-8
41-
//! Caller->>Main: commit()
42-
//! Main->>Main: store latest revision, count -= 1
43-
//! Note right of BG: Waiting (count > threshold)
44-
//! end
33+
//! For example, with `commit_count = 10` the pool starts with 10 permits and
34+
//! `persist_threshold = 5`. After 5 commits the available permits drop to 5,
35+
//! triggering a persist that releases all 5 consumed permits back to the pool.
4536
//!
46-
//! Caller->>Main: close()
47-
//! Main->>BG: shutdown signal
48-
//! BG->>Disk: persist last committed revision
49-
//! Note right of Disk: Latest committed revision is persisted
50-
//! ```
37+
//! See [`PersistWorker`] for a sequence diagram illustrating this flow.
5138
5239
use std::{
5340
num::NonZeroU64,
@@ -78,6 +65,48 @@ pub enum PersistError {
7865
}
7966

8067
/// Handle for managing the background persistence thread.
68+
///
69+
/// # Sequence diagram
70+
///
71+
/// Below is an example when `commit_count` is set to 10:
72+
///
73+
/// ```mermaid
74+
/// sequenceDiagram
75+
/// participant Caller
76+
/// participant Main as Main Thread
77+
/// participant BG as Background Thread
78+
/// participant Disk
79+
///
80+
/// Note over Main: permits = 10
81+
///
82+
/// loop Commits 1-4
83+
/// Caller->>Main: commit()
84+
/// Main->>Main: store latest revision, permits -= 1
85+
/// Note right of BG: Sleeping (permits > threshold)
86+
/// end
87+
///
88+
/// Note over Main: permits = 6
89+
///
90+
/// Caller->>Main: commit() (5th)
91+
/// Main->>Main: store latest revision, permits -= 1
92+
/// Note over Main: permits = 5 = threshold
93+
/// Main->>BG: notify persist_ready
94+
/// BG->>Disk: persist latest revision
95+
/// BG->>BG: release 5 permits
96+
/// Note over Main: permits = 10
97+
///
98+
/// loop Commits 6-8
99+
/// Caller->>Main: commit()
100+
/// Main->>Main: store latest revision, permits -= 1
101+
/// Note right of BG: Sleeping (permits > threshold)
102+
/// end
103+
///
104+
/// Caller->>Main: close()
105+
/// Main->>BG: shutdown signal
106+
/// BG->>Disk: persist last committed revision
107+
/// Note right of Disk: Latest committed revision is persisted
108+
/// ```
109+
#[cfg_attr(doc, aquamarine::aquamarine)]
81110
#[derive(Debug)]
82111
pub(crate) struct PersistWorker {
83112
/// The background thread responsible for persisting commits async.

0 commit comments

Comments
 (0)