-
Notifications
You must be signed in to change notification settings - Fork 301
Open
Labels
bugSomething is not working, or not working as intendedSomething is not working, or not working as intended
Description
Problem
last_network_status in RelayPool is accessed from network monitor callback (on network_monitor_queue) and from @RelayPoolActor context without proper synchronization at the boundary.
Location
damus/Core/Nostr/RelayPool.swift lines 87-105
nonisolated init(ndb: Ndb?, keypair: Keypair? = nil) {
network_monitor.pathUpdateHandler = { [weak self] path in
Task { await self?.pathUpdateHandler(path: path) }
}
network_monitor.start(queue: network_monitor_queue)
}
private func pathUpdateHandler(path: NWPath) async {
if (path.status == .satisfied) && self.last_network_status != path.status { // RACE
await self.connect_to_disconnected()
}
self.last_network_status = path.status // RACE
}Root Cause
The pathUpdateHandler closure runs on network_monitor_queue but accesses actor-isolated state. Multiple rapid network changes can create concurrent access.
Impact
- Network state tracking becomes unreliable
- Relays may fail to reconnect when network changes
Related Issues
- investigate: profile path update, dispatch queue #3432 (profile path update dispatch queue)
Suggested Fix
Make pathUpdateHandler explicitly @RelayPoolActor isolated, or use atomic storage for last_network_status.
Test Plan
- Test rapid network state changes
- Verify relay reconnection works correctly
- Run with ThreadSanitizer
Changelog-Fixed: Fix race condition in RelayPool network status tracking
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
bugSomething is not working, or not working as intendedSomething is not working, or not working as intended