Commit 96ac65e
committed
fix(session-roots): deadlock in record_resolution on a changed resolution
record_resolution held a DashMap read guard from `last_resolution.get()`
across `last_resolution.insert()` on the same key. DashMap routes a key to a
single shard RwLock, so requesting the write lock for insert() while the
get() Ref is still alive self-deadlocks. The dead branch is reached exactly
when a session already has a recorded resolution AND the new value differs —
i.e. every time a client's effective FeatureSet *changes* (binding created/
edited, roots arrive, space reroute). That is the core path of workspace-root
routing, so in production this would hang the task that records the new
resolution and fires list_changed.
The 64 integration tests passed because none drove a Some(..) -> different
Some(..) transition; the unit test record_resolution_flips_on_change does
(fallback -> bound) and hung the whole gateway lib test binary, which is how
this surfaced.
Fix: read the prior value into an owned bool and let the read guard drop at
the end of that statement (is_some_and), then insert with no guard held.
Verified: gateway lib suite now 116 passed (was hanging indefinitely).
Signed-off-by: Mohammod Al Amin Ashik <maa.ashik00@gmail.com>1 parent 9bdafa9 commit 96ac65e
1 file changed
Lines changed: 14 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
154 | | - | |
155 | | - | |
156 | | - | |
157 | | - | |
158 | | - | |
159 | | - | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
160 | 166 | | |
| 167 | + | |
| 168 | + | |
161 | 169 | | |
162 | 170 | | |
163 | 171 | | |
| |||
0 commit comments