Skip to content

fix(cron): spawn scheduler loop at startup so scheduled jobs auto-fire#873

Merged
senamakel merged 3 commits into
tinyhumansai:mainfrom
graycyrus:fix/cron-scheduler-startup
Apr 24, 2026
Merged

fix(cron): spawn scheduler loop at startup so scheduled jobs auto-fire#873
senamakel merged 3 commits into
tinyhumansai:mainfrom
graycyrus:fix/cron-scheduler-startup

Conversation

@graycyrus
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus commented Apr 24, 2026

Summary

  • Spawn cron::scheduler::run(config) at startup in src/core/jsonrpc.rs, gated on config.cron.enabled
  • The scheduler polling loop (due_jobs() every ~5s) was never started — only "Run Now" via direct RPC worked
  • Follows the same tokio::spawn + Config::load_or_init() pattern as the update scheduler

Test plan

  • Create an agent cron job with */1 * * * * schedule
  • Verify it auto-fires within ~1 minute without clicking "Run Now"
  • Verify proactive delivery + alerts tab notification arrive automatically
  • Verify shell jobs also auto-fire
  • Verify cron.enabled = false prevents the scheduler from starting

Closes #830

Summary by CodeRabbit

  • Bug Fixes

    • Cron scheduler background task now reliably starts during server initialization and is controlled by configuration.
  • Dependencies

    • Tightened versions for the dialog and command-palette libraries and adjusted the Sentry Vite plugin placement.
  • Documentation

    • Added project-memory notes clarifying scheduler behavior, updated tooling/TypeScript check commands, missing test tooling dependencies, and guidance on pre-push/ESLint usage.

The cron scheduler polling loop (`cron::scheduler::run()`) was never
spawned at startup — only "Run Now" worked via direct RPC. Add
`tokio::spawn` for the scheduler in `src/core/jsonrpc.rs`, gated on
`config.cron.enabled`, following the same pattern as the update
scheduler.

Also install missing deps from upstream PR tinyhumansai#745 (command palette).

Closes tinyhumansai#830
@graycyrus graycyrus requested a review from a team April 24, 2026 10:09
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 45eeed7b-2244-4989-ab81-f61196eec6c6

📥 Commits

Reviewing files that changed from the base of the PR and between 9053712 and c491224.

📒 Files selected for processing (1)
  • app/package.json
✅ Files skipped from review due to trivial changes (1)
  • app/package.json

📝 Walkthrough

Walkthrough

Adds startup spawning of the cron scheduler (gated by config.cron.enabled), updates project memory/docs about the change and tooling notes, and adjusts app dependency versions in package.json.

Changes

Cohort / File(s) Summary
Core server startup
src/core/jsonrpc.rs
Spawns the cron scheduler as a background Tokio task during server init; loads OpenHuman config, gates scheduler on config.cron.enabled, and logs errors for config load or scheduler termination.
Project memory & docs
.claude/memory.md
Adds entries documenting the cron scheduler startup fix and notes about build/tooling and missing TypeScript dev deps for the command palette.
Frontend deps
app/package.json
Adjusts dependency versions (@radix-ui/react-dialog^1.1.15, cmdk^1.1.1) and repositions @sentry/vite-plugin in devDependencies; reflects package dependency updates.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Server as JsonRPC Server
    participant Config as OpenHuman Config
    participant Cron as Cron Scheduler
    rect rgba(200,230,255,0.5)
    Server->>Config: load config on startup
    Config-->>Server: config (cron.enabled true/false)
    alt cron.enabled == true
        Server->>Cron: tokio::spawn(cron::scheduler::run(config))
        Cron-->>Server: started (background)
    else cron.enabled == false
        Server-->>Server: log "cron disabled"
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibbled bytes at break of dawn,
Spun a cron that once was gone.
A config gate, a background hop,
Jobs now wake and never stop.
Packages snug — we hop along! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title directly describes the primary change: spawning the cron scheduler loop at startup to enable auto-firing of scheduled jobs.
Linked Issues check ✅ Passed All requirements from issue #830 are implemented: cron scheduler spawned at startup in src/core/jsonrpc.rs, gated by config.cron.enabled, with test plan validation included.
Out of Scope Changes check ✅ Passed Changes include necessary dependency updates for command palette feature from PR #745 and project memory documentation, all aligned with PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/core/jsonrpc.rs (1)

749-759: Consider: Graceful shutdown for the scheduler loop.

The cron::scheduler::run() function (per context snippet from scheduler.rs:19-54) runs an infinite loop with no cancellation token. When the server receives a shutdown signal (Line 799), this spawned task will be forcibly aborted rather than gracefully stopped.

This matches the existing pattern used by other background tasks (update scheduler, channel listeners), so it's not a regression. However, for future improvement, consider passing a CancellationToken to allow the scheduler to complete any in-flight job execution before shutdown.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/jsonrpc.rs` around lines 749 - 759, The spawned cron scheduler task
currently calls crate::openhuman::cron::scheduler::run(config).await without any
cancellation token, so the task is force-aborted on server shutdown; modify the
spawn logic to create a CancellationToken (or equivalent used elsewhere in the
project), clone/propagate it into the task, and change the call to run(config,
token) so the scheduler's run function can observe cancellation and gracefully
finish in-flight jobs; also wire the token to the server shutdown notifier used
elsewhere so it is triggered when the server begins shutdown.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/package.json`:
- Line 68: In package.json remove the duplicate "@testing-library/user-event"
entry from the dependencies block so it only appears under devDependencies;
specifically delete the dependencies entry for "@testing-library/user-event":
"^14.6.1" and keep the existing devDependencies entry intact to ensure testing
utilities are not shipped to production.

---

Nitpick comments:
In `@src/core/jsonrpc.rs`:
- Around line 749-759: The spawned cron scheduler task currently calls
crate::openhuman::cron::scheduler::run(config).await without any cancellation
token, so the task is force-aborted on server shutdown; modify the spawn logic
to create a CancellationToken (or equivalent used elsewhere in the project),
clone/propagate it into the task, and change the call to run(config, token) so
the scheduler's run function can observe cancellation and gracefully finish
in-flight jobs; also wire the token to the server shutdown notifier used
elsewhere so it is triggered when the server begins shutdown.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 49bd23bf-5b94-4174-b5b9-b897bfb29918

📥 Commits

Reviewing files that changed from the base of the PR and between b81d04d and 9053712.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (3)
  • .claude/memory.md
  • app/package.json
  • src/core/jsonrpc.rs

Comment thread app/package.json Outdated
Testing utilities should not be shipped to production.
@graycyrus
Copy link
Copy Markdown
Contributor Author

Re: CodeRabbit nitpick on graceful shutdown via CancellationToken — acknowledged, but this matches the existing pattern for all other background tasks (update scheduler, channel listeners). Adding graceful shutdown is a separate concern and out of scope for this fix.

@senamakel senamakel merged commit 9d14006 into tinyhumansai:main Apr 24, 2026
8 of 9 checks passed
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
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.

fix(cron): spawn scheduler loop at startup so scheduled jobs auto-fire

2 participants