MCPcopy Create free account
hub / github.com/ByBrawe/opencode-loop / maybeRunDueJobs

Function maybeRunDueJobs

src/index.js:1237–1361  ·  view source on GitHub ↗
(directory, client, sessionID, options = {})

Source from the content-addressed store, hash-verified

1235 // active-run guard, recover instead of waiting for another manual command.
1236 if ((live.type === "busy" || live.type === "retry") && options.recoverStaleActive !== false && staleActiveRun(sessionID)) {
1237 sessionStatuses.set(sessionID, "idle")
1238 sessionStatusSeenAt.set(sessionID, now())
1239 return "idle"
1240 }
1241 sessionStatuses.set(sessionID, live.type)
1242 sessionStatusSeenAt.set(sessionID, now())
1243 return live.type
1244 }
1245
1246 const fallback = activeRuns.has(sessionID) && !staleActiveRun(sessionID) ? "busy" : "idle"
1247 sessionStatuses.set(sessionID, fallback)
1248 sessionStatusSeenAt.set(sessionID, now())
1249 return fallback
1250}
1251
1252async function sessionIsIdle(client, sessionID, directory, options = {}) {
1253 return await sessionStatusType(client, sessionID, directory, options) === "idle"
1254}
1255
1256function scheduleIdleWork(directory, client, sessionID) {
1257 const previous = idleTimers.get(sessionID)
1258 if (previous) clearTimeout(previous)
1259 const timer = setTimeout(() => {
1260 idleTimers.delete(sessionID)
1261 Promise.resolve()
1262 .then(async () => {
1263 if (!await sessionIsIdle(client, sessionID, directory)) {
1264 await scheduleDueWork(directory, client, sessionID, BUSY_RETRY_MS)
1265 return
1266 }
1267 await finalizeActiveRun(directory, client, sessionID)
1268 if (!await sessionIsIdle(client, sessionID, directory)) {
1269 await scheduleDueWork(directory, client, sessionID, BUSY_RETRY_MS)
1270 return
1271 }
1272 await maybeRunDueJobs(directory, client, sessionID)
1273 })
1274 .catch((error) => {
1275 toast(client, `Loop idle handler failed: ${sdkErrorMessage(error)}`, "error").catch(() => {})
1276 appendLoopLog(directory, "idle-error", { sessionID, error: sdkErrorMessage(error) }).catch(() => {})
1277 })
1278 }, IDLE_DEBOUNCE_MS)
1279 idleTimers.set(sessionID, timer)
1280}
1281
1282function jobDueAt(job, current = now()) {
1283 if (isGoalJob(job) && ["completed", "blocked", "cleared"].includes(job.goalStatus)) return Infinity
1284 if (!job.enabled || job.paused) return Infinity
1285 if (job.maxRuns > 0 && (job.runCount || 0) >= job.maxRuns) return Infinity
1286 if (job.watchPaths?.length) return Infinity
1287 const created = Date.parse(job.createdAt || new Date().toISOString())
1288 if (job.maxRuntimeMs > 0 && current - created >= job.maxRuntimeMs) return current
1289 if (job.intervalMs === 0) return current
1290 if (!job.lastRunAt) return current
1291 return job.lastRunAt + (job.intervalMs || 0)
1292}
1293
1294function nextDueDelay(state) {

Callers 5

startHeartbeatFunction · 0.85
scheduleIdleWorkFunction · 0.85
startWatchdogFunction · 0.85
scheduleDueWorkFunction · 0.85
runNowFunction · 0.85

Calls 15

rememberSessionFunction · 0.85
rescheduleFunction · 0.85
nowFunction · 0.85
finalizeActiveRunFunction · 0.85
sessionIsIdleFunction · 0.85
toastFunction · 0.85
clearActiveRunFunction · 0.85
readStateFunction · 0.85
watchChangedFunction · 0.85
dueJobsFunction · 0.85
writeStateFunction · 0.85
notifyJobFunction · 0.85

Tested by

no test coverage detected