schedule:install
php mitosis schedule:install
✓ Scheduler install complete: `scheduled_runs` created. Add one line to the system crontab and the schedule in app/routes/cli.php takes it from there:
* * * * * cd /srv/app && php mitosis schedule:run
Requires Clarity 1.5.0 or newer. Creates the one table Scheduler needs — the run record that doubles as its cluster-wide lock. Run it once per database context, before you add the crontab line.
--context selects a connection, as everywhere else. An application running the
scheduler on a second database installs the table there too.
Order does not have to be perfect
The crontab line added before this command produces a tick that exits 1 every
minute and names schedule:install — loudly, rather than silently doing nothing.
That is deliberate: a scheduler whose failure mode is silence is the worst kind.
Safe to run again
The table is skipped when it already exists, and nothing is changed:
✓ Scheduler is already installed: `scheduled_runs` was already present.
Guarded on whether the table is present rather than on CREATE TABLE IF NOT
EXISTS, because that clause covers the table but not the indexes, which are emitted as
separate statements MySQL has no IF NOT EXISTS for.
What it creates
One row per attempted run of one job: id (UUIDv7),
job, due_at, state, started_at,
finished_at, duration_ms, failure_reason,
created_at, updated_at.
Three indexes, and the first of them is the whole design:
-
A unique index on
(job, due_at)— the mutex. Two nodes whose crontabs fire in the same minute both try to insert the same pair, and exactly one succeeds. This is not there to dedupe anything; losing it does not degrade the scheduler, it silently doubles every job on every node. (job, state)— the in-flight check and the reaper, both of which ask for one job's running rows.due_at— pruning old run records.
job is 128 characters rather than the default 255 so the unique key stays
comfortably inside MySQL's index-length limit under utf8mb4.
Why this is separate from setup
setup creates sessions and caches, the
two tables Clarity itself owns and every app needs. Scheduling is opt-in, so an application
that schedules nothing should not carry a table it never reads — the same decision
checkout:install exists for.
A command rather than a shipped migration because Clarity's resources/ directory
is excluded from the Composer distribution, so a migration file there would never reach anyone
who installs the framework normally.
Where it fits
cp .env_example .env
php mitosis setup # sessions + caches — always
php mitosis schedule:install # only if you schedule work
php mitosis migrate # your own app's migrations
# then, in the system crontab, on every node:
* * * * * cd /srv/app && php mitosis schedule:run
No > /dev/null 2>&1 on that line — see
schedule:run for why.
Next steps
- Scheduler — registering jobs, and what the claim guarantees.
- schedule:run — the heartbeat this table records.