Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion advanced/state-management.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ persistence_manager.modify_device(|device| {
Device state uses two separate locks with different roles:

- **`device_snapshot` (`std::sync::RwLock<Arc<Device>>`)**: read by `get_device_snapshot()`. Readers never contend with writers — they take a brief `std::sync` read lock to clone the `Arc`, then release immediately. The snapshot is updated inside the `tokio::sync::RwLock` write guard in `modify_device`, so readers always see fully committed state.
- **`device` (`tokio::sync::RwLock<Device>`)**: write-locked inside `modify_device()`. Only store-adapter code that needs `&mut Device` trait access (`get_device_arc()`) takes a read lock here directly.
- **`device` (`tokio::sync::RwLock<Device>`)**: write-locked inside `modify_device()`. As of [whatsapp-rust#1226](https://github.com/oxidezap/whatsapp-rust/pull/1226), the Signal store adapters (`SignalProtocolStoreAdapter`, `SenderKeyAdapter`) no longer take a read lock here on every operation — they hold `Arc<PersistenceManager>` and call `get_device_snapshot()` instead. The old read-lock approach let concurrent Signal reads coexist, but `tokio::sync::RwLock` is write-preferring. A `process_command` write arriving mid-round-trip queued behind a held read guard, and every later reader then queued behind that writer. So one slow backend round-trip could delay a device mutation and, through it, every other Signal operation waiting on the lock. Adapters no longer hold this lock at all, so that cascade can no longer start. `get_device_arc()` still returns a handle to this lock for any caller that needs `&mut Device` trait access directly; store adapters are no longer among them.

In practice: `get_device_snapshot()` is contention-free for readers, and the tokio write lock is only held during actual mutations (rare).

Expand Down