Zoo

staging

← back to the zoo

21. Jobs on a clock

An app can run a script every few minutes.

Add `cron = bin/job.php every 5m` to ratcloud.conf: root runs it as the app, never two at once, with its output in RC_FACTS/log.txt.

This is the code serving the zoo right now: read from disk for this request, from commit 77ff74344d (staging). The zoo's own self-check fetches this page and compares it byte for byte with the file it runs.

exhibits/21-jobs-on-a-clock.php sha256 03fa07eca00a · raw

1<?php
2// Exhibit 21. `cron = bin/tick.php every 5m` in ratcloud.conf runs bin/tick.php as the zoo, every
3// five minutes, with the same environment a web request gets. It writes the time here.
4return [
5    "n" => 21, "wing" => "Building",
6    "title" => "Jobs on a clock",
7    "promise" => "An app can run a script every few minutes.",
8    "block" => "Add `cron = bin/job.php every 5m` to ratcloud.conf: root runs it as the app, never two at once, with its output in RC_FACTS/log.txt.",
9    "files" => ["bin/tick.php", "ratcloud.conf"],
10    "show" => function (?array $me): string {
11        $t = meta("last_tick");
12        return "<p>Last tick: <b>" . ago($t ? (int)$t : null) . "</b>, written by the zoo's own five-minute job.</p>";
13    },
14    "check" => function (): array {
15        $t = (int)meta("last_tick");
16        if (!$t) return [false, "the job has never ticked"];
17        $m = intdiv(time() - $t, 60);
18        return $m > 10 ? [false, "the last tick was $m minutes ago"] : [true, "the last tick was " . ($m ? "$m minute(s)" : "under a minute") . " ago"];
19    },
20];

bin/tick.php sha256 a5c7147b6fc9 · raw

1<?php
2// Exhibit 21's job: every five minutes (ratcloud.conf), write the time. That is all.
3require __DIR__ . "/../lib/zoo.php";
4meta_set("last_tick", (string)time());

ratcloud.conf sha256 25c85b08e06f · raw

1# The zoo's settings. rc renders nginx and the jobs from this; a mistake refuses the push.
2name = Zoo
3description = See every building block working
4# 10: anyone may listen to the counter. 11: `auth` makes nginx ask index.php first.
5channels = counter, mine auth
6# 21: the clock. 22: the self-check that turns every self-running exhibit into a light.
7cron = bin/tick.php every 5m, bin/selfcheck.php every 5m
8max_body = 1M
9# 23: after each nightly backup, root counts the guestbook in the backup copy.
10backup_check = zoo.db guestbook