fix(k1): stabilize live recovery and media admission

This commit is contained in:
DCCONSTRUCTIONS
2026-08-22 00:03:01 +03:00
parent 7217244886
commit eaad9deda1
29 changed files with 1645 additions and 199 deletions
+52
View File
@@ -37,6 +37,7 @@ from k1link.device_plugins.xgrids_k1.facade import (
ACTION_PHYSICAL_COMMAND_RECONCILE,
ACTION_PHYSICAL_COMMAND_REOPEN_RETIRED_RECONCILIATION,
ACTION_PHYSICAL_COMMAND_RETIRE_UNAVAILABLE,
ACTION_STATE_READ,
ACTION_STREAM_START_LIVE,
ACTION_STREAM_START_REPLAY,
ACTION_STREAM_STOP,
@@ -1285,6 +1286,57 @@ def test_sync_runtime_actions_run_outside_the_api_event_loop() -> None:
assert service.thread_id != event_loop_thread
def test_state_reads_are_single_flight_and_survive_one_cancelled_waiter() -> None:
class BlockingStateService(FakeXgridsService):
def __init__(self) -> None:
super().__init__()
self.state_calls = 0
self.started = threading.Event()
self.release = threading.Event()
def state(self) -> dict[str, Any]:
self.state_calls += 1
self.started.set()
if not self.release.wait(timeout=2):
raise AssertionError("state read was not released by the test")
return {"phase": "idle", "revision": self.state_calls}
service = BlockingStateService()
adapter = XgridsK1PluginFacade(service)
def invocation(invocation_id: str) -> RuntimeActionInvocation:
return RuntimeActionInvocation(
invocation_id=invocation_id,
plugin_id=adapter.plugin_id,
action_id=ACTION_STATE_READ,
requested_at=datetime.now(UTC),
parameters={},
)
async def exercise() -> None:
first = asyncio.create_task(adapter.invoke(invocation("state-read-first")))
while not service.started.is_set():
await asyncio.sleep(0)
second = asyncio.create_task(adapter.invoke(invocation("state-read-second")))
await asyncio.sleep(0.02)
assert service.state_calls == 1
first.cancel()
with pytest.raises(asyncio.CancelledError):
await first
assert service.state_calls == 1
service.release.set()
assert await second == {"phase": "idle", "revision": 1}
assert await adapter.invoke(invocation("state-read-fresh")) == {
"phase": "idle",
"revision": 2,
}
asyncio.run(exercise())
assert service.state_calls == 2
def test_runtime_requires_successful_handshake_before_dispatch() -> None:
adapter = XgridsK1PluginFacade(FakeXgridsService())
runtime = _in_process_runtime(adapter, activate=False)