Wait for a deadline instead of polling for one
Docs / docs (push) Successful in 25s
Playwright Tests / test-playwright (1, 2) (push) Successful in 2m23s
Playwright Tests / test-playwright (2, 2) (push) Successful in 2m0s
pre-commit / pre-commit (push) Failing after 4m31s
Test Backend / test-backend (push) Successful in 2m55s
Compose Smoke Test / test-compose (push) Successful in 35s
Playwright Tests / merge-reports (push) Successful in 1m11s

The timer thread promoted due work on a fixed one-second tick, so every
delayed item was 0-1000ms late whatever the load — measured on the house
at 705ms mean on a rollershutter stop, which is 2-4% of a 26-second
travel and accumulates in the position the motor node believes it is at.
It now sleeps to the soonest deadline and is woken when a nearer one is
scheduled, which measures 0.9ms end to end through Redis.

A promoted timer also went to the back of the queue. It goes into a due
lane of its own that `claim` reads first, so work that has waited out a
deadline is not held up by work that is merely queued.

Beside it, in the same code: seeding a message now bumps its version, so
a re-put flow's synchronous nodes no longer wait forever on a value that
is sitting in state; the consumer group drops the consumers of engines
that are gone (138 had accumulated on this installation); and the cast
that closes the long-standing `xclaim` mypy error.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-27 11:51:58 +02:00
co-authored by Claude Opus 5
parent e2f97d36e4
commit c3675688c8
6 changed files with 311 additions and 41 deletions
@@ -72,6 +72,37 @@ def test_synchronous_node_waits_for_all_inputs_to_be_fresh():
assert sorted(runs) == ["eager", "sync"]
def test_a_seeded_value_counts_as_having_arrived():
"""A re-put flow used to come back with its synchronous nodes wedged.
Seeding wrote the value and not its version, and version 0 reads as
"never published" — so the node reported active and ok and never ran
again, with the value it was waiting for sitting right there in state.
"""
runs: list[str] = []
def sync(a, b, params):
runs.append("sync")
return None
def sensor_b(params):
return {"b": 2.0}
b = node("b", sensor_b, provides=[spec("b")])
sync_node = node(
"sync", sync, requires=[spec("a"), spec("b")], params={"synchronous": True}
)
Pipeline(
nodes=[b, sync_node],
max_workers=1,
initial_values={"f.a": 1.0},
)
b.inject()
assert runs == ["sync"]
def test_increment_and_multi_get():
state = MemoryState()