Skip to content

fix(pipes): don't fire newly-installed or stale cron pipes immediately#3607

Merged
louis030195 merged 1 commit into
mainfrom
claude/silly-albattani-8daaa2
May 25, 2026
Merged

fix(pipes): don't fire newly-installed or stale cron pipes immediately#3607
louis030195 merged 1 commit into
mainfrom
claude/silly-albattani-8daaa2

Conversation

@louis030195

Copy link
Copy Markdown
Collaborator

Summary

  • Wall-clock cron pipes (e.g. every day at 7am) were firing immediately on install instead of waiting for their next scheduled slot. A user reported creating a "morning brief" pipe at 5:39pm via chat — it fired 12 seconds later (scheduler: queuing pipe 'morning-brief' (scheduled)).
  • Root cause at crates/screenpipe-core/src/pipes/mod.rs:3352: newly-discovered pipes had last_run = UNIX_EPOCH, so cron.after(epoch).next() returned a 1970-01-01 slot which is always <= now ⇒ fire.
  • Same trap whenever the app was off across a scheduled slot — on restart the cron would catch up immediately instead of waiting.
  • Fix: anchor the cron lookup at max(last_run, now - 5min) so we only fire when the most recent slot is actually within a small grace window. Stale missed slots are skipped; the pipe waits for the next future slot.

The 5-minute CRON_GRACE_WINDOW absorbs scheduler-tick latency (~1s) and brief sleep/wake cycles without firing stale catch-up runs.

Interval schedules (every 1h, every 30m) are untouched — those have always been "fire N seconds after last_run" semantics.

Test plan

  • cargo test --lib -p screenpipe-core pipes:: — all 131 tests pass
  • New regression tests:
    • test_should_run_cron_fresh_install_waits — newly-installed pipe (last_run = epoch) does NOT fire immediately
    • test_should_run_cron_stale_last_run_waits — pipe whose app was off for 3 days does NOT fire immediately on restart
    • test_should_run_cron_within_grace_fires — slot hit moments ago, last_run far in past → still fires
  • Existing test_should_run_human_daily updated to use minute-precision cron so the slot is "right now" regardless of test wall-clock time
  • Manual: install a pipe at 5pm with schedule: every day at 9am — verify it does NOT fire on install and DOES fire at 9am the next day

A newly-installed pipe has no `last_run`, so the scheduler defaulted to
`UNIX_EPOCH` and asked `cron.after(epoch).next()` — a 1970 slot, which
is always `<= now`, so the pipe fired on the very next scheduler tick.
Same trap when the app was off across a scheduled slot: on restart the
cron would catch up immediately instead of waiting for the next slot.

For wall-clock cron ("every day at 7am") this is wrong — a user who
installs a morning brief at 5:39pm doesn't want it firing 12 seconds
later.

Anchor the cron lookup at `max(last_run, now - 5min)` so we only fire
when we're actually inside a recent scheduled slot. Stale missed slots
(deep past) are skipped and the pipe waits for its next future slot.
The 5-minute window absorbs scheduler-tick latency and brief downtime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@louis030195 louis030195 merged commit 1ed982d into main May 25, 2026
19 of 22 checks passed
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.

1 participant