Skip to content

fix(dsl): compute cron wait at execution time, not at df.start() time#183

Open
Copilot wants to merge 3 commits into
mainfrom
copilot/bugfix-df-wait-for-schedule
Open

fix(dsl): compute cron wait at execution time, not at df.start() time#183
Copilot wants to merge 3 commits into
mainfrom
copilot/bugfix-df-wait-for-schedule

Conversation

Copy link
Copy Markdown

Copilot AI commented May 27, 2026

df.wait_for_schedule() pre-computed wait_seconds at graph construction time. Any delay between df.start() and when the BGW actually runs the WAIT_SCHEDULE node caused the timer to fire early — potentially before the intended cron tick.

Approach

The orchestration must stay deterministic, so wall-clock reads must happen inside an activity. The fix captures the target timestamp (next cron tick) at DSL time for replay stability, then delegates the actual duration computation to a new activity that runs max(0, target - now()) at true execution time.

Changes

  • src/dsl.rs — store target_timestamp (RFC 3339) in node config instead of wait_seconds; cron expression is still validated eagerly
  • src/activities/compute_cron_wait.rs (new) — activity that receives target_timestamp, computes remaining seconds at execution time
  • src/orchestrations/execute_function_graph.rsexecute_wait_schedule_node schedules compute_cron_wait activity first, feeds the result into schedule_timer
  • src/registry.rs — register new activity
  • src/explain.rs — update WAIT_SCHEDULE display: WAIT '<cron>' (until <timestamp>) instead of (<secs>s)
  • src/lib.rs — update unit test to assert target_timestamp present and wait_seconds absent

Config shape change

Before:

{"cron_expr": "*/5 * * * *", "wait_seconds": 142}

After:

{"cron_expr": "*/5 * * * *", "target_timestamp": "2026-05-27T14:45:00+00:00"}

Copilot AI and others added 2 commits May 27, 2026 14:36
Store target_timestamp (RFC 3339) in WAIT_SCHEDULE node config instead of
pre-computing wait_seconds at df.start() time.

Add compute_cron_wait activity that receives the target timestamp and computes
max(0, target - now()) at actual execution time. The orchestration node
schedules this activity first, then passes the result to schedule_timer.

This keeps the orchestration deterministic (no wall-clock I/O inside
orchestration code) while correctly measuring remaining time at the moment
the background worker actually processes the WAIT_SCHEDULE node — preventing
early wake-ups when there is a delay between df.start() and BGW execution.

Changes:
- src/dsl.rs: store target_timestamp instead of wait_seconds
- src/activities/compute_cron_wait.rs: new activity for wall-clock I/O
- src/activities/mod.rs: register new module
- src/orchestrations/execute_function_graph.rs: schedule compute_cron_wait
  activity before scheduling the timer
- src/registry.rs: register compute_cron_wait activity
- src/explain.rs: show target timestamp in WAIT_SCHEDULE node output
- src/lib.rs: update unit test to assert target_timestamp is present

Co-authored-by: pinodeca <32303022+pinodeca@users.noreply.github.com>
- compute_cron_wait.rs: mention RFC 3339 in invalid timestamp error message
- dsl.rs: add comment documenting RFC 3339 format contract with activity

Co-authored-by: pinodeca <32303022+pinodeca@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix df.wait_for_schedule to compute wait at execution time fix(dsl): compute cron wait at execution time, not at df.start() time May 27, 2026
Copilot AI requested a review from pinodeca May 27, 2026 14:40
@pinodeca pinodeca marked this pull request as ready for review May 31, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: df.wait_for_schedule computes cron wait at DSL time, not execution time

2 participants