-
Notifications
You must be signed in to change notification settings - Fork 3.1k
feat(scheduler): add internal scheduler for self-hosted environments #2518
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: staging
Are you sure you want to change the base?
Conversation
|
@majiayu000 is attempting to deploy a commit to the Sim Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryThis PR adds a built-in scheduler for self-hosted environments to trigger scheduled workflows by polling Major Changes:
Issues Found:
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant App as Next.js App
participant Instrumentation as instrumentation-node.ts
participant Scheduler as Internal Scheduler
participant API as /api/schedules/execute
participant DB as Database
participant Workflow as Workflow Executor
Note over App,Instrumentation: Application Startup
App->>Instrumentation: register()
Instrumentation->>Scheduler: initializeInternalScheduler()
alt ENABLE_INTERNAL_SCHEDULER=true
Scheduler->>Scheduler: Check CRON_SECRET exists
Scheduler->>Scheduler: startInternalScheduler()
Scheduler->>Scheduler: Set isRunning flag
Scheduler->>API: GET /api/schedules/execute<br/>(Bearer token auth)
Note over Scheduler,API: Immediate first poll
loop Every INTERNAL_SCHEDULER_INTERVAL_MS (default: 60s)
Scheduler->>Scheduler: Check if previous poll running
alt Previous poll still running
Scheduler->>Scheduler: Skip this cycle
else Can proceed
Scheduler->>Scheduler: Set isRunning = true
Scheduler->>API: GET /api/schedules/execute<br/>(Authorization: Bearer CRON_SECRET)
API->>API: verifyCronAuth()
API->>DB: Query due schedules<br/>(nextRunAt <= now)
DB-->>API: Return due schedules
API->>DB: Update lastQueuedAt
loop For each due schedule
API->>Workflow: Execute workflow
end
API-->>Scheduler: Return {executedCount: N}
Scheduler->>Scheduler: Set isRunning = false
alt executedCount > 0
Scheduler->>Scheduler: Log executed count
end
end
end
else ENABLE_INTERNAL_SCHEDULER=false
Note over Scheduler: Scheduler disabled,<br/>relies on external cron
end
Note over App,Scheduler: Graceful Shutdown
App->>Scheduler: SIGTERM/SIGINT
Scheduler->>Scheduler: stopInternalScheduler()
Scheduler->>Scheduler: clearInterval()
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Comments (5)
-
apps/sim/lib/core/config/env.ts, line 128-129 (link)style: Use
z.boolean()instead ofz.string()for boolean environment variablesFor consistency with other boolean flags in this file (like
DISABLE_REGISTRATION,BILLING_ENABLED,TRIGGER_DEV_ENABLED), use proper boolean type:Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
-
apps/sim/lib/scheduler/internal-scheduler.ts, line 126-133 (link)style: Multiple signal handlers registered on every initialization
If
initializeInternalScheduler()is called multiple times (e.g., in hot reload or tests), this adds duplicate SIGTERM/SIGINT handlers. Consider checking if handlers already exist or usingprocess.once(): -
apps/sim/lib/scheduler/internal-scheduler.ts, line 79 (link)style: Handle invalid
INTERNAL_SCHEDULER_INTERVAL_MSvaluesNumber()returnsNaNfor invalid strings. Consider validating or using parseInt with error handling: -
docker-compose.prod.yml, line 11-26 (link)logic: Missing required
INTERNAL_API_SECRETenvironment variableThe app requires
INTERNAL_API_SECRET(min 32 chars) to start, as defined inapps/sim/lib/core/config/env.ts:28. Add it afterENCRYPTION_KEY. -
apps/sim/lib/scheduler/internal-scheduler.ts, line 106-107 (link)style: If
ENABLE_INTERNAL_SCHEDULERis changed toz.boolean()in env.ts (as suggested in another comment), update comparison from=== 'true'to=== true
6 files reviewed, 5 comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additional Comments (5)
-
apps/sim/lib/scheduler/internal-scheduler.ts, line 127-133 (link)logic: multiple registrations of
SIGTERMandSIGINThandlers will occur ifinitializeInternalScheduler()is called multiple times (e.g., during hot reloads in development). This could lead to memory leaks or unexpected behavior. -
apps/sim/lib/scheduler/internal-scheduler.ts, line 34 (link)logic: fallback to
http://localhost:3000will not work correctly in containerized environments where the app might not be accessible on localhost. The scheduler is running inside the container and needs to call its own HTTP endpoint. -
apps/sim/lib/scheduler/internal-scheduler.ts, line 79 (link)logic:
Number(undefined)returnsNaN, which will causesetIntervalto fire repeatedly without delay -
docker-compose.prod.yml, line 25 (link)logic: the default value
default-cron-secret-change-meis insecure and could allow unauthorized access to scheduled workflows. Remove the default or use an empty string to force users to set their own secret. -
apps/sim/instrumentation-node.ts, line 119-125 (link)style: caught errors are only logged. If scheduler initialization fails silently, scheduled workflows won't run and users may not notice. Consider adding startup health checks or more visible warnings.
6 files reviewed, 5 comments
…dioai#2481) The realtime service network policy was missing the custom egress rules section that allows configuration of additional egress rules via values.yaml. This caused the realtime pods to be unable to connect to external databases (e.g., PostgreSQL on port 5432) when using external database configurations. The app network policy already had this section, but the realtime network policy was missing it, creating an inconsistency and preventing the realtime service from accessing external databases configured via networkPolicy.egress values. This fix adds the same custom egress rules template section to the realtime network policy, matching the app network policy behavior and allowing users to configure database connectivity via values.yaml.
Adds built-in scheduler that periodically polls /api/schedules/execute to trigger scheduled workflows in self-hosted environments. Enable by setting ENABLE_INTERNAL_SCHEDULER=true (enabled by default in docker-compose.prod.yml). Also requires CRON_SECRET to be configured. Fixes simstudioai#1870
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8778b62 to
d5c46a8
Compare
Summary
/api/schedules/executeto trigger scheduled workflowsdocker-compose.prod.ymlfor self-hosted setupsENABLE_INTERNAL_SCHEDULER,CRON_SECRET, andINTERNAL_SCHEDULER_INTERVAL_MSenvironment variablesTest plan
Fixes #1870