Step a paused flow, and deliver what a rate limit held back
Three things a pause and an interval were quietly losing:
- A rebuild builds a fresh pipeline, so nothing is paused any more and no
resume ever comes for what the old one parked. Release it on rebuild.
- POST /flows/{name}/step takes the oldest parked item and runs that one wave
while the flow stays paused, so a held-back cascade can be walked through.
Nothing parked answers plainly rather than failing.
- A per-port interval was leading-edge only: a producer going quiet inside the
window left the consumer on the value before it. The held value is kept and
a flush item scheduled on the queue's existing timer, so the window ends with
a delivery. One timer in flight per node, and none without a queue to run it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7LwYgJfpkbLCTeiAf8U4A
This commit is contained in:
@@ -127,6 +127,36 @@ def test_work_for_a_paused_flow_is_held_and_released_on_resume():
|
||||
assert seen == [1.0]
|
||||
|
||||
|
||||
def test_a_step_runs_one_held_item_and_leaves_the_flow_paused():
|
||||
pipeline, source, _state, seen = _pipeline_with_a_consumer()
|
||||
service = ExecutionService(pipeline._queue)
|
||||
service.bind(pipeline)
|
||||
|
||||
pipeline.pause("f")
|
||||
source.inject({"reading": 1.0})
|
||||
source.inject({"reading": 2.0})
|
||||
for item in pipeline._queue.claim(10, 10):
|
||||
service._run_item(item)
|
||||
assert seen == []
|
||||
|
||||
assert service.step("f") == "f.source"
|
||||
|
||||
assert seen == [1.0]
|
||||
# Still paused, and the second value is still waiting for the next step.
|
||||
assert pipeline.is_paused("f")
|
||||
assert [i.outputs for i in pipeline._queue.unpark("f")] == [{"f.reading": 2.0}]
|
||||
|
||||
|
||||
def test_stepping_a_flow_with_nothing_held_says_so_rather_than_failing():
|
||||
pipeline, _source, _state, _seen = _pipeline_with_a_consumer()
|
||||
service = ExecutionService(pipeline._queue)
|
||||
service.bind(pipeline)
|
||||
|
||||
pipeline.pause("f")
|
||||
|
||||
assert service.step("f") is None
|
||||
|
||||
|
||||
def test_work_for_a_stopped_flow_is_dropped():
|
||||
pipeline, source, state, seen = _pipeline_with_a_consumer()
|
||||
stopped = Pipeline(
|
||||
|
||||
Reference in New Issue
Block a user