Skip to content

Commit 31ce6df

Browse files
committed
docs: document cron schedule helpers
1 parent 875c9fd commit 31ce6df

8 files changed

Lines changed: 19 additions & 0 deletions

File tree

src/cron/schedule-identity.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Builds stable identities for cron scheduling inputs. */
12
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
23
import { coerceFiniteScheduleNumber } from "./schedule-number.js";
34
import { normalizeCronStaggerMs } from "./stagger.js";
@@ -34,6 +35,8 @@ function schedulePayloadFromRecord(
3435
const tz = readString(schedule, "tz");
3536
const staggerMs = readStaggerMs(schedule);
3637
const kind =
38+
// Infer legacy shorthand schedule shapes when kind is missing so timer
39+
// identity remains stable across old persisted jobs and normalized jobs.
3740
rawKind === "at" || rawKind === "every" || rawKind === "cron"
3841
? rawKind
3942
: at

src/cron/schedule-number.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Coerces cron schedule number fields with strict finite-number parsing. */
12
import { parseStrictFiniteNumber } from "@openclaw/normalization-core/number-coercion";
23

34
/** Coerces schedule numeric fields without accepting partial or non-finite numbers. */

src/cron/schedule.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Computes at/every/cron schedule timestamps with bounded Croner caching. */
12
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
23
import { Cron } from "croner";
34
import { parseAbsoluteTimeMs } from "./parse.js";
@@ -27,6 +28,8 @@ function resolveCachedCron(expr: string, timezone: string): Cron {
2728
return cached;
2829
}
2930
if (cronEvalCache.size >= CRON_EVAL_CACHE_MAX) {
31+
// Expression parsing is expensive enough to cache, but cron jobs can be
32+
// edited dynamically; keep the cache bounded and LRU-like.
3033
const oldest = cronEvalCache.keys().next().value;
3134
if (oldest) {
3235
cronEvalCache.delete(oldest);

src/cron/service/agent-watchdog.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Timeout watchdogs for isolated cron agent setup and execution phases. */
12
import type {
23
CronAgentExecutionPhase,
34
CronAgentExecutionPhaseUpdate,
@@ -111,6 +112,8 @@ export function createCronAgentWatchdog(params: {
111112
const previousPhase = activeExecution?.phase;
112113
activeExecution = { ...activeExecution, ...info };
113114
const stage = info.phase ? CRON_AGENT_PHASE_WATCHDOG_STAGE[info.phase] : undefined;
115+
// A fallback attempt can return to setup-like phases after execution began;
116+
// re-arm pre-execution timing so the fallback path cannot stall silently.
114117
if (
115118
state === "executing" &&
116119
previousPhase === "before_agent_reply" &&

src/cron/service/execution-errors.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Formats stable cron timeout and execution error messages. */
12
import { formatEmbeddedAgentExecutionPhase } from "../../agents/embedded-agent-runner/execution-phase.js";
23
import type { CronAgentExecutionStarted } from "../types.js";
34

src/cron/service/failure-alerts.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Resolves and emits cron failure-alert notifications. */
12
import { normalizeOptionalLowercaseString } from "@openclaw/normalization-core/string-coerce";
23
import { resolveFailoverReasonFromError } from "../../agents/failover-error.js";
34
import type { CronFailureNotificationDelivery, CronJob, CronMessageChannel } from "../types.js";
@@ -78,6 +79,8 @@ export function resolveFailureAlert(
7879
const mode = jobConfig?.mode ?? globalConfig?.mode;
7980
const explicitTo = normalizeTo(jobConfig?.to);
8081

82+
// Announce alerts inherit the job delivery target; webhook alerts require an
83+
// explicit alert target so chat recipients are not reused as URLs.
8184
return {
8285
after: clampPositiveInt(jobConfig?.after ?? globalConfig?.after, DEFAULT_FAILURE_ALERT_AFTER),
8386
cooldownMs: clampNonNegativeInt(

src/cron/service/initial-delivery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Resolves create-time default delivery for new cron jobs. */
12
import type { CronDelivery, CronJobCreate } from "../types.js";
23

34
/** Resolves default cron delivery for new jobs when callers omit explicit delivery config. */

src/cron/service/jobs.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/** Cron job scheduling, validation, creation, and patch helpers. */
12
import crypto from "node:crypto";
23
import {
34
normalizeOptionalString,
@@ -343,6 +344,7 @@ function assertDeliverySupport(job: Pick<CronJob, "sessionTarget" | "delivery">)
343344
return;
344345
}
345346
if (job.delivery.mode === "webhook") {
347+
// Webhook delivery is standalone and does not need an isolated chat target.
346348
return;
347349
}
348350
const isIsolatedLike =
@@ -844,6 +846,8 @@ export function applyJobPatch(
844846
);
845847
}
846848
if (job.sessionTarget === "main" && job.delivery?.mode !== "webhook") {
849+
// Main-session jobs cannot auto-announce; keep only an empty failure
850+
// destination object when the patch is clearing nested fields.
847851
const failureDestination = job.delivery?.failureDestination;
848852
job.delivery =
849853
failureDestination && !hasConcreteFailureDestination(failureDestination)

0 commit comments

Comments
 (0)