Scheduled Jobs
Cron jobs and scheduled tasks are a perfect fit for Island Pulse. They run unattended, often at odd hours, and you only care about two things: did it start on time, and did it finish successfully?
The three-push pattern
Model every scheduled job with three posts: start, optional mid-run progress, and done.
#!/bin/bashPULSE_URL="YOUR_WEBHOOK_URL"JOB="nightly-report"
# 1. Startcurl -s -X POST "$PULSE_URL" \ -H "Content-Type: application/json" \ -d "{ \"job_id\": \"$JOB\", \"layout\": \"progress\", \"message\": \"Report generation started\", \"metric\": \"Step 1/3\", \"progress\": 0.05, \"status\": \"running\" }"
# 2. Your actual job./generate_report.sh || { curl -s -X POST "$PULSE_URL" \ -H "Content-Type: application/json" \ -d "{\"job_id\":\"$JOB\",\"layout\":\"progress\",\"message\":\"Report failed during generation\",\"progress\":0,\"status\":\"failed\"}" exit 1}
# 3. Donecurl -s -X POST "$PULSE_URL" \ -H "Content-Type: application/json" \ -d "{ \"job_id\": \"$JOB\", \"layout\": \"progress\", \"message\": \"Report ready. Sent to 12 recipients.\", \"metric\": \"Done\", \"progress\": 1.0, \"status\": \"success\" }"Wrap this with your cron scheduler (crontab, systemd.timer, etc.) and you’ll see every run’s status on your Lock Screen without checking a log.
Python wrapper
For Python-based jobs, use a context manager to automatically send start/done/fail notifications:
import requests, contextlib, traceback
PULSE_URL = "YOUR_WEBHOOK_URL"
@contextlib.contextmanagerdef pulse_job(job_id: str, start_message: str = "Job started"): """Context manager that sends start, success, and failure notifications.""" def notify(msg, status, progress=None): payload = { "job_id": job_id, "layout": "progress", "message": msg, "status": status, } if progress is not None: payload["progress"] = progress requests.post(PULSE_URL, json=payload, timeout=5)
notify(start_message, "running", 0.05) try: yield notify # caller can call notify() mid-job for progress updates notify("Completed successfully", "success", 1.0) except Exception as e: notify(f"Failed: {str(e)[:60]}", "failed", 0) raise
# Usagewith pulse_job("invoice-sync", "Syncing invoices from Stripe") as update: invoices = fetch_invoices() # step 1 update("Processing invoices…", "running", 0.4) process(invoices) # step 2 update("Uploading to accounting…", "running", 0.8) upload(invoices) # step 3Node.js / TypeScript
const PULSE_URL = process.env.ISLAND_PULSE_URL!;
async function notify(jobId: string, message: string, status: "running" | "success" | "failed", progress?: number) { await fetch(PULSE_URL, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ job_id: jobId, layout: "progress", message, status, progress }), });}
async function runNightlySync() { const job = "nightly-sync"; await notify(job, "Sync started", "running", 0.0);
try { await fetchData(); await notify(job, "Data fetched, transforming…", "running", 0.5); await transformAndLoad(); await notify(job, `Sync complete. ${Date.now() - start}ms`, "success", 1.0); } catch (err) { await notify(job, `Sync failed: ${err.message}`, "failed"); throw err; }}Heartbeat / dead man’s switch
Post a success update from each cron run to confirm it ran on schedule. If a run is missed (job died, server down), the activity goes stale, you’ll notice it hasn’t updated.
# Add to the end of any cron job as a health checkcurl -s -X POST "YOUR_WEBHOOK_URL" \ -H "Content-Type: application/json" \ -d "{ \"job_id\": \"heartbeat\", \"layout\": \"score\", \"metric\": \"$(date +%H:%M)\", \"message\": \"Last successful run\", \"status\": \"running\" }"The metric shows the time of the last successful run. If it stops updating, you know the job missed a cycle.
Recommended naming
Use names that make it obvious what failed when you’re half-awake at 2am:
daily-reportinvoice-syncdb-backup-prodcache-warmemail-digestAvoid generic names like cron-1 or job, they mean nothing in your Lock Screen history.