Crescendo Lab Docs
English
Sign up

Scheduled jobs

A scheduled job makes one HTTP call to one of your organization's apps on a clock, like Google Cloud Scheduler.

Last updated

What a job is made of#

The call reaches whichever version is live at that moment.

FieldDescription
AppThe container app to call.
PathAppended to the app's address. Starts with /; a query string is allowed. For example /tasks/daily.
MethodGET, POST, PUT, PATCH or DELETE; POST by default. A body is sent only with POST, PUT and PATCH.
ScheduleA five-field cron expression: minute, hour, day of month, month, day of week. At most once a minute.
Time zoneAsia/Taipei by default.

Some cron expressions:

ExpressionRuns
0 9 * * *Every day at 09:00
*/15 * * * *Every 15 minutes
0 8 * * 1Every Monday at 08:00
0 0 1 * *At 00:00 on the 1st of every month

Create a job#

  1. Add an endpoint to your app For example POST /tasks/daily, with the recurring work in it. Deploy it and go live.
  2. Create the job Open Deploy › Scheduled jobs, choose the app, and enter the path and schedule.
  3. Run it once by hand Use Run now, then check the response code and log in the run history.

Check that a call came from the schedule#

By default a call carries no proof of where it came from. Choose one of these:

  • Set your own header on the job, such as X-Cron-Secret, store the value as a secret of the app, and compare the two in your code.
  • Turn on the signed token. The call then carries Authorization: Bearer <JWT>; verify it against https://api.agentlab.cresclab.com/.well-known/jwks.json with aud = franky:app:<app ID>.

How runs behave#

ItemBehavior
OverlapRuns never overlap. A run that comes due while the previous one is still going is skipped.
DeliveryAt least once, so a run can arrive twice. De-duplicate on the X-Franky-Run-Id header.
Retries0 by default, at most 5.
Deadline15 seconds to 30 minutes; 3 minutes by default.
server.js
const runId = req.headers["x-franky-run-id"];
if (await alreadyHandled(runId)) {
  res.writeHead(200).end();
  return;
}