fix(issue-18): the wrapper's subscriber waits for the first event up to the wall clock
The subscriber is started before the injection, and the injection itself (idle handshake, quiescence, delivery grace) can take tens of seconds, so a first-event budget of T + K x N measured from the subscription could expire before `started` was even possible. The wrapper now passes --ack-timeout <wall clock>: it judges delivery with _wait_started (T from the injection) and reaps the subscriber on failure; K x N applies from the first event on. A standalone subscriber keeps T + K x N. Documented in MESSAGING.md 4.3. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
1 parent
135d76f903
commit
7e1d3f0815
2 files changed
+7
-2
No files matched your search
@@ -228,7 +228,11 @@ EOF
|
||||
|
||||
# 3) START THE SUBSCRIBER
|
||||
local logf="$REGISTRY_DIR/$JOB_ID.subscriber.out"
|
||||
local sub_extra_args=()
|
||||
# Before the first event the subscriber is bounded by the wall clock only:
|
||||
# delivery (T from the injection, which happens after the subscriber is
|
||||
# up and can take a while itself) is judged by _wait_started, and a failed
|
||||
# injection reaps the subscriber. From the first event on, K x N applies.
|
||||
local sub_extra_args=(--ack-timeout "$TIMEOUT")
|
||||
[ -n "$_disp_tok" ] && sub_extra_args+=(--expect-dispatch-token "$_disp_tok")
|
||||
_is_remote "$AGENT_SESSION" && sub_extra_args+=(--remote)
|
||||
"$PY" "$SCRIPT_DIR/scripts/job_subscriber.py" --registry-dir "$REGISTRY_DIR" \
|
||||
@@ -401,7 +405,7 @@ EOF
|
||||
|
||||
# Start subscriber
|
||||
local logf="$REGISTRY_DIR/${JOB_ID}.iter_${iteration}_${display_role}.subscriber.out"
|
||||
local loop_sub_args=(--attempt-id "$attempt")
|
||||
local loop_sub_args=(--attempt-id "$attempt" --ack-timeout "$TIMEOUT")
|
||||
[ -n "$_disp_tok" ] && loop_sub_args+=(--expect-dispatch-token "$_disp_tok")
|
||||
_is_remote "$current_session" && loop_sub_args+=(--remote)
|
||||
"$PY" "$SCRIPT_DIR/scripts/job_subscriber.py" --registry-dir "$REGISTRY_DIR" \
|
||||
|
||||
@@ -339,6 +339,7 @@ The subscriber acts as the central execution watchdog:
|
||||
* **Dual Timeout Semantics**:
|
||||
1. **Wall-Clock Timeout**: Calculated relative to absolute startup time (`wall_deadline = start + wall_timeout`). It acts as a hard budget limit, guarding against an agent hanging indefinitely.
|
||||
2. **Activity Idle Timeout**: Measured as the difference between the current monotonic time and the last packet arrival time (`idle_left = idle_timeout - (now - last_event)`). If the agent fails to publish any event (heartbeats and retained state included) for the duration of the idle window - K x N under the Issue #18 contract - the subscriber aborts and exits with code 2.
|
||||
* **Idle budget before the first event (Issue #18)**: a standalone subscriber allows `ack_timeout_sec + idle_timeout_sec` before the first accepted event (the injection has to produce `started`). The delegate wrapper passes `--ack-timeout <wall clock>` instead: it judges delivery itself with `_wait_started` (T from the injection, which happens after the subscriber is up) and reaps the subscriber when that fails, so the subscriber's own idle clock only starts with the first event.
|
||||
* **Retained state and seq gaps (Issue #18)**: the subscriber also subscribes to `<topic_prefix>/state`; a retained terminal state resolves the job at (re)connect, any state resets the idle clock, and a seq jump on either topic is written to the audit log as `seq_gap`. With `--remote` (or `transport: remote`) accepted `started`/terminal events are mirrored into the local job record.
|
||||
|
||||
---
|
||||
|
||||
Reference in new issue
Block a user