-
Notifications
You must be signed in to change notification settings - Fork 38
Bug: force_complete_request does not handle Running state — potential coordinator deadlock #396
Description
Summary
RefreshCoordinator::force_complete_request() only handles the Completing and Idle states. If begin_completion() panics with an "unexpected key" error, the coordinator state is restored to Running before the panic. The RefreshCompletionGuard::drop then calls force_complete_request(), which hits the _ => {} wildcard arm — leaving the coordinator permanently stuck in Running.
Root Cause
In crates/pet/src/jsonrpc.rs:
- Line 148-150 (
begin_completion): On key mismatch, state is restored toRunning(active)before panicking - Line 273-278 (
RefreshCompletionGuard::drop): Callsforce_complete_request()during stack unwind - Line 210-220 (
force_complete_request): Only transitionsCompleting → Idle. TheRunningstate matches_ => {}— a silent no-op.
Impact
After the panic, the coordinator is stuck in Running with no thread owning the refresh. All future refresh requests call wait_until_idle() and hang forever — deadlocking the JSONRPC server.
While the "unexpected key" panic is a defensive assertion that shouldn't fire in normal operation, if it ever fires (e.g., due to a future code change or race condition), the server becomes completely unresponsive.
Proposed Fix
Either:
- Have
force_complete_request()also handle theRunningstate by transitioning toIdle+notify_all(), OR - Return a
Resultfrombegin_completion()instead of panicking, allowing proper error recovery
Introduced By
PR #386 (d3a060f — fix: deduplicate concurrent refresh requests)