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
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:
@@ -395,13 +395,24 @@ class Pipeline:
|
||||
self.replace_flow(flow, [])
|
||||
|
||||
def _seed(self, initial_values: dict[str, Any] | None) -> None:
|
||||
"""Give messages a starting value, without overwriting one already there."""
|
||||
"""Give messages a starting value, without overwriting one already there.
|
||||
|
||||
A seeded value counts as having arrived. Writing it without its version
|
||||
left the value in state at version 0, which `_check_synchronous_ready`
|
||||
reads as "never published" — so a flow that was dropped and recreated
|
||||
came back with its synchronous nodes waiting on inputs that were sitting
|
||||
right there, reporting `active` and `ok` and never running again.
|
||||
"""
|
||||
if not initial_values:
|
||||
return
|
||||
seeded = []
|
||||
with self._state.lock():
|
||||
for name, value in initial_values.items():
|
||||
if name not in self._state:
|
||||
self._state[name] = value
|
||||
seeded.append(name)
|
||||
if seeded:
|
||||
self._state.increment_multi([self._version_key(name) for name in seeded])
|
||||
|
||||
def get_node_by_id(self, nid: str) -> Node | None:
|
||||
return next((n for n in self._nodes if n.id == nid), None)
|
||||
|
||||
Reference in New Issue
Block a user