[object Object]

← back to Dw Scrape Scheduler

add daily dispatcher launchd wrapper + plist (staggered monthly fleet scrape); wrapper proven end-to-end (day-13 selected 2 vendors, staged clean)

ec519a3d145336932e346e731da77fd0376cf9b4 · 2026-07-13 00:54:25 -0700 · Steve Abrams

Files touched

Diff

commit ec519a3d145336932e346e731da77fd0376cf9b4
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Mon Jul 13 00:54:25 2026 -0700

    add daily dispatcher launchd wrapper + plist (staggered monthly fleet scrape); wrapper proven end-to-end (day-13 selected 2 vendors, staged clean)
---
 launchd/com.steve.dw-scrape-dispatcher.plist | 26 ++++++++++++++++++++++++++
 scripts/dispatch-run.sh                      | 22 ++++++++++++++++++++++
 2 files changed, 48 insertions(+)

diff --git a/launchd/com.steve.dw-scrape-dispatcher.plist b/launchd/com.steve.dw-scrape-dispatcher.plist
new file mode 100644
index 0000000..a8fa96f
--- /dev/null
+++ b/launchd/com.steve.dw-scrape-dispatcher.plist
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0"><dict>
+  <key>Label</key><string>com.steve.dw-scrape-dispatcher</string>
+  <key>ProgramArguments</key>
+    <array>
+      <string>/bin/bash</string>
+      <string>/Users/macstudio3/Projects/dw-scrape-scheduler/scripts/dispatch-run.sh</string>
+    </array>
+  <key>WorkingDirectory</key><string>/Users/macstudio3/Projects/dw-scrape-scheduler</string>
+  <!-- DAILY at 04:15; the dispatcher self-selects vendors whose day-of-month == today,
+       so the fleet is spread across the month (1-2 vendors on any given day). -->
+  <key>StartCalendarInterval</key>
+    <dict>
+      <key>Hour</key><integer>4</integer>
+      <key>Minute</key><integer>15</integer>
+    </dict>
+  <key>RunAtLoad</key><false/>
+  <key>StandardOutPath</key><string>/tmp/dw-scrape-dispatcher.log</string>
+  <key>StandardErrorPath</key><string>/tmp/dw-scrape-dispatcher.log</string>
+  <key>EnvironmentVariables</key>
+    <dict>
+      <key>PATH</key><string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
+      <key>HOME</key><string>/Users/macstudio3</string>
+    </dict>
+</dict></plist>
diff --git a/scripts/dispatch-run.sh b/scripts/dispatch-run.sh
new file mode 100755
index 0000000..78d743f
--- /dev/null
+++ b/scripts/dispatch-run.sh
@@ -0,0 +1,22 @@
+#!/bin/bash
+# Daily launchd entrypoint for the staggered monthly fleet scrape.
+# Runs the dispatcher, which itself selects ONLY the vendors whose assigned
+# day-of-month == today (concurrency cap 2). Most days that's 0-2 vendors, so
+# the fleet is spread across the month and never thundered all at once.
+# Local-models-only: feed adapters need no model; Gemini enrich is never invoked.
+set -uo pipefail
+export PATH="/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"
+
+PROJ="/Users/macstudio3/Projects/dw-scrape-scheduler"
+LOG="/tmp/dw-scrape-dispatcher.log"
+cd "$PROJ" || { echo "$(date '+%F %T') FATAL cd failed" >>"$LOG"; exit 1; }
+
+echo "===== $(date '+%F %T') dispatcher START (day $(date '+%d')) =====" >>"$LOG"
+node dispatcher.js >>"$LOG" 2>&1
+rc=$?
+echo "===== $(date '+%F %T') dispatcher END rc=$rc =====" >>"$LOG"
+
+# Best-effort CNCP heartbeat (never blocks the run)
+curl -s -X POST http://127.0.0.1:3333/api/wins -H 'Content-Type: application/json' \
+  -d "{\"project\":\"dw-scrape-scheduler\",\"title\":\"daily fleet-scrape tick\",\"summary\":\"staggered monthly vendor scrape, day $(date '+%d'), rc=$rc\"}" >/dev/null 2>&1 || true
+exit $rc

← 755fba7 auto-save: 2026-07-13T00:51:43 (4 files) — data/manifest.jso  ·  back to Dw Scrape Scheduler  ·  (newest)