Internals
Current lock ordering, empty-on-open indexes and failure behavior.
Forum holds a shared Strand and a private HashMap<EntryId, Vec<u8>> behind a Tokio read/write lock. Its stored JSON records are TupleEntry::Write { id, tuple } and TupleEntry::Take { write_id }.
| Operation | Lock and mutation order |
|---|---|
write | Acquire Strand write lock → append record → acquire tuple-map write lock → insert tuple. Both guards remain live until the function returns. |
read | Acquire tuple-map read lock → scan for byte equality → clone one matching value. |
take | Acquire tuple-map write lock → remove a match → acquire Strand write lock → append tombstone. |
Opposite write/take lock ordering permits deadlock. The take removal is not undone when its append fails. These boundaries rule out describing the current implementation as a production exactly-once queue.
Forum::new starts with an empty map. SDK ForumStore::open constructs the same type without replay. A caller can read retained TupleEntry records from a separately retained Strand handle to implement its own projection, but the current public Forum API does not import such a projection into its private map. Replaying by calling write would append new records, not restore the original state.