Skip to content

Commit d673daa

Browse files
authored
docs: expand design documentation with new sections on storage layer and concurrency (#141)
- Added a section on the storage layer, detailing the `Store` trait family, concrete stores, and the rationale behind `StoreMetrics`. - Updated the concurrency documentation to clarify the `ConcurrentStoreRead` and `ConcurrentStore` trait family, including their sequential and concurrent split. - Enhanced the design overview to provide a clearer architectural perspective, linking to relevant design documents for better navigation. These additions improve the comprehensiveness of the documentation, aiding developers in understanding the cache library's structure and concurrency strategies.
1 parent 6cf722d commit d673daa

11 files changed

Lines changed: 1851 additions & 552 deletions

File tree

docs/design/concurrency.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,11 @@ Tracked roughly in priority order:
359359
- [TTL design](ttl.md) — applied case for `ConcurrentExpiring<C>`
360360
- [Cache trait hierarchy](trait-hierarchy.md) — read/mutate split and
361361
object-safety rationale
362-
- [Stores](../stores/README.md)`ConcurrentStoreRead` /
363-
`ConcurrentStore` trait family
362+
- [Storage layer](storage.md)`ConcurrentStoreRead` /
363+
`ConcurrentStore` trait family rationale and the
364+
sequential/concurrent split
365+
- [Stores](../stores/README.md) — runtime-behaviour reference for
366+
each concrete store
364367
- [`src/store/traits.rs`](../../src/store/traits.rs) — concurrent
365368
store traits
366369
- [`src/traits.rs`](../../src/traits.rs)`ConcurrentCache` marker

docs/design/design.md

Lines changed: 846 additions & 327 deletions
Large diffs are not rendered by default.

docs/design/metrics.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,20 +378,23 @@ is a **separate**, simpler structure that ships unconditionally
378378
store-layer implementation tracks:
379379

380380
```rust,ignore
381+
#[non_exhaustive]
381382
pub struct StoreMetrics {
382383
pub hits: u64,
383384
pub misses: u64,
384385
pub inserts: u64,
385386
pub updates: u64,
386387
pub removes: u64,
387388
pub evictions: u64,
389+
pub expirations: u64,
388390
}
389391
```
390392

391393
The two systems coexist:
392394

393395
- `StoreMetrics` is the store-layer baseline. Always present, always
394-
cheap, six counters.
396+
cheap, seven counters. `expirations` stays at `0` on stores that
397+
do not own a TTL surface.
395398
- `src/metrics/` (feature-gated) is the policy-layer detailed
396399
metrics — recorder traits, snapshots, exporter, per-policy signals.
397400

docs/design/non-goals.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,17 @@ text exporter. It does not provide:
106106
Use your monitoring stack for those. cachekit exposes enough counters to make
107107
policy tuning possible without making the cache own observability.
108108

109+
`MetricsCell` (the crate-private interior-mutability wrapper used by
110+
`&self` recorder paths) is **not** a substitute for `AtomicU64`. It is
111+
sound only when increments happen under exclusive external
112+
synchronization — single-threaded, `&mut self`, or behind a write
113+
lock / `Mutex`. A shared `RwLock::read` guard does not serialize
114+
readers and so is not sufficient protection. Counters reachable from a
115+
read-locked `&self` path must use `AtomicU64` (or escalate to a write
116+
lock before recording). The contract is restated on the `unsafe impl
117+
Sync` block in [`src/metrics/cell.rs`](../../src/metrics/cell.rs) and
118+
in the [Metrics design](metrics.md#metricscell-interior-mutability-under-external-lock).
119+
109120
## Not a Policy Research Playground at the Cost of Hot Paths
110121

111122
New policies are welcome, but they must fit the crate's constraints:

docs/design/storage.md

Lines changed: 447 additions & 0 deletions
Large diffs are not rendered by default.

docs/design/style-guide.md

Lines changed: 160 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
# Documentation Style Guide
22

3-
## Goals
3+
This style guide covers two related but distinct concerns:
4+
5+
- **Rustdoc style** for module- and item-level documentation inside
6+
`src/`. The audience is a Rust developer reading the API.
7+
- **Design-doc style** for the prose docs in `docs/design/`. The
8+
audience is a contributor (or future maintainer) trying to
9+
understand why a piece of cachekit looks the way it does.
10+
11+
Both styles share the same goals: make behaviour, invariants, and
12+
trade-offs clear without verbosity, and keep examples compile-ready
13+
and focused.
14+
15+
## Rustdoc style
16+
17+
### Goals
18+
419
- Keep module docs consistent across the codebase.
520
- Make behavior, invariants, and trade-offs clear without verbosity.
621
- Ensure examples compile and demonstrate a single, focused use case.
722

8-
## Module Doc Layout
23+
### Module doc layout
24+
925
Use `//!` and follow this order:
26+
1027
- Architecture
1128
- Key Components
1229
- Core Operations
@@ -17,11 +34,14 @@ Use `//!` and follow this order:
1734
- Thread Safety
1835
- Implementation Notes
1936

20-
## Item Docstrings
21-
Use `///` with a one-sentence summary. Mention invariants or complexity only when
22-
they matter. Avoid Args/Returns sections unless behavior is non-obvious.
37+
### Item docstrings
38+
39+
Use `///` with a one-sentence summary. Mention invariants or complexity
40+
only when they matter. Avoid Args/Returns sections unless behavior is
41+
non-obvious.
42+
43+
### Template
2344

24-
## Template
2545
```rust
2646
//! ## Architecture
2747
//! ...
@@ -51,6 +71,139 @@ they matter. Avoid Args/Returns sections unless behavior is non-obvious.
5171
//!
5272
//! ## Implementation Notes
5373
//! ...
54-
///
74+
5575
/// Brief summary of behavior.
5676
```
77+
78+
## Design-doc style
79+
80+
Files in `docs/design/` follow a shared shape so a reader who has
81+
finished one knows what to expect from the next. The shape is not a
82+
strict template — sections are added or omitted as the topic
83+
warrants — but the meta-conventions below are uniform.
84+
85+
### Status preamble
86+
87+
Every design doc opens with a blockquote that names what the doc
88+
covers and links its immediate siblings. The convention is
89+
`> Status: <one-sentence framing>. Companion to <links>.`
90+
91+
```markdown
92+
> Status: design rationale for the concurrent surface that ships today
93+
> behind the `concurrency` feature flag. Companion to the cross-cutting
94+
> principles in [`docs/design/design.md`](design.md) §3 and the trait
95+
> rationale in [`docs/design/trait-hierarchy.md`](trait-hierarchy.md).
96+
```
97+
98+
The preamble does three things in one paragraph:
99+
100+
- Names the doc's scope.
101+
- States the implementation status (shipped, partially shipped, deferred).
102+
- Anchors the doc in the wider design corpus by linking siblings.
103+
104+
### Section structure
105+
106+
- Numbered top-level sections (`§1`, `§2`, …) are encouraged when other
107+
docs may want to cross-reference specific sections. `design.md`,
108+
`ttl.md`, and `trait-hierarchy.md` all do this.
109+
- Closer sections, in order, when relevant:
110+
- **Trade-offs** — explicit tables or side-by-side prose comparing
111+
alternatives.
112+
- **Failure modes** — what breaks under stress, panic, contention.
113+
- **Future directions** / **Roadmap** — what is deferred, in rough
114+
priority order.
115+
- **Adding a new X** — checklist for the most common contribution
116+
pattern (new policy, new capability trait, new metric, etc.).
117+
- **When not to use X** — explicit boundaries for users.
118+
- **See also** — links to sibling design docs, source files, and
119+
external references.
120+
121+
### Tables for trade-offs
122+
123+
When two or more options have different trade-offs, use a table rather
124+
than a bulleted list. Tables make it easy to scan one column for one
125+
property and force the writer to give every option the same set of
126+
properties.
127+
128+
```markdown
129+
| Property | Option A | Option B |
130+
|----------|----------|----------|
131+
| Cost |||
132+
| Memory |||
133+
```
134+
135+
### Diagrams
136+
137+
Use fenced code blocks tagged `text` for ASCII diagrams. Avoid Mermaid
138+
or other rich diagram formats — plain text renders in every tool
139+
(rustdoc, GitHub, terminal `less`) without configuration. See the
140+
hierarchy diagram in `trait-hierarchy.md` for the conventional shape.
141+
142+
```text
143+
┌──────────────────┐
144+
│ Cache<K, V> │
145+
└────────┬─────────┘
146+
│ extends
147+
┌────────────┼────────────┐
148+
▼ ▼ ▼
149+
Capability1 Capability2 Capability3
150+
```
151+
152+
### Source citations
153+
154+
Every concrete claim that names a type, trait, or method should link
155+
the source file. Use relative paths
156+
(`[`src/policy/lru.rs`](../../src/policy/lru.rs)`) so the docs work
157+
both on GitHub and in local clones. When citing a specific feature
158+
gate, name the feature inline (`gated by `#[cfg(feature = "ttl")]`).
159+
160+
### Cross-references
161+
162+
- Refer to sibling design docs by filename, not display title:
163+
`[concurrency](concurrency.md)` rather than `[Concurrency design](...)`.
164+
This survives renames better and matches the rest of the corpus.
165+
- When citing a specific section, append the section number or anchor:
166+
`[design.md §3](design.md)`, `[concurrency.md §"Failure modes"](concurrency.md#failure-modes)`.
167+
168+
### Tone
169+
170+
- Direct, declarative prose. "The wrapper takes a write lock", not
171+
"The wrapper will take a write lock".
172+
- Trade-offs are stated explicitly, not buried in passive voice.
173+
- Marketing language is out of place. "Excellent", "powerful",
174+
"blazing fast" — replace with the property that motivated the
175+
adjective.
176+
- It is acceptable, and often correct, to say "this is a known sharp
177+
edge" or "this is the wrong trait for that surface" when it is.
178+
179+
### `See Also` closer
180+
181+
Every design doc ends with a `## See Also` section. The conventional
182+
order is:
183+
184+
1. **Sibling design docs** with a one-sentence framing of each link.
185+
2. **Source files** that contain the canonical implementation.
186+
3. **External references** (Rust API Guidelines, research papers,
187+
Wikipedia entries) when relevant.
188+
189+
The framing matters: a bare list of links is less useful than a list
190+
where each entry says why the reader might follow it.
191+
192+
### Adding a new design doc
193+
194+
Checklist:
195+
196+
1. **Pick a clear single topic.** If you are documenting two concerns,
197+
split into two docs and link them.
198+
2. **Write the status preamble first.** Naming the scope up front
199+
keeps the rest of the doc honest.
200+
3. **Number top-level sections** if they're likely to be
201+
cross-referenced from elsewhere.
202+
4. **Add a `See Also` block** to siblings that should know about the
203+
new doc, and add a corresponding bullet to
204+
[`docs/index.md`](../index.md).
205+
5. **Link from `design.md`'s See Also block** so the new doc is
206+
reachable from the index design overview.
207+
6. **Mirror trade-offs as tables** when there are alternatives.
208+
7. **Close with `When not to use X`** (or the equivalent) — explicit
209+
boundaries are part of the contract.

docs/design/trait-hierarchy.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,5 +411,8 @@ GDS lands keeps the surface honest.
411411
- [Read-only traits](../guides/read-only-traits.md) — user-facing
412412
guidance on the `peek` / `get` split
413413
- [`src/traits.rs`](../../src/traits.rs) — the canonical definitions
414-
- [`src/store/traits.rs`](../../src/store/traits.rs) — parallel
415-
trait family at the store layer (sequential + concurrent)
414+
- [Storage layer](storage.md) — parallel trait family at the store
415+
layer (sequential + concurrent), with the same `&V` vs. `Arc<V>`
416+
split reasoning
417+
- [`src/store/traits.rs`](../../src/store/traits.rs) — canonical
418+
store-trait definitions

0 commit comments

Comments
 (0)