pixivflow 2.11.0 → 2.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/commands/SchedulerCommand.d.ts.map +1 -1
- package/dist/commands/SchedulerCommand.js +79 -32
- package/dist/commands/SchedulerCommand.js.map +1 -1
- package/dist/commands/SchedulerRunOnceCommand.d.ts.map +1 -1
- package/dist/commands/SchedulerRunOnceCommand.js +5 -1
- package/dist/commands/SchedulerRunOnceCommand.js.map +1 -1
- package/dist/commands/scheduler-runtime.d.ts +4 -2
- package/dist/commands/scheduler-runtime.d.ts.map +1 -1
- package/dist/commands/scheduler-runtime.js +86 -53
- package/dist/commands/scheduler-runtime.js.map +1 -1
- package/dist/config/types.d.ts +24 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/delivery/DeliveryOutbox.d.ts.map +1 -1
- package/dist/delivery/DeliveryOutbox.js +10 -3
- package/dist/delivery/DeliveryOutbox.js.map +1 -1
- package/dist/delivery/HttpMultipartDelivery.d.ts.map +1 -1
- package/dist/delivery/HttpMultipartDelivery.js +19 -3
- package/dist/delivery/HttpMultipartDelivery.js.map +1 -1
- package/dist/delivery/types.d.ts +12 -0
- package/dist/delivery/types.d.ts.map +1 -1
- package/dist/package.json +1 -1
- package/dist/scheduler/MultiScheduleManager.d.ts +9 -12
- package/dist/scheduler/MultiScheduleManager.d.ts.map +1 -1
- package/dist/scheduler/MultiScheduleManager.js +31 -15
- package/dist/scheduler/MultiScheduleManager.js.map +1 -1
- package/dist/scheduler/OccurrenceResolver.d.ts +90 -0
- package/dist/scheduler/OccurrenceResolver.d.ts.map +1 -0
- package/dist/scheduler/OccurrenceResolver.js +127 -0
- package/dist/scheduler/OccurrenceResolver.js.map +1 -0
- package/dist/scheduler/ScheduleTriggerServer.d.ts +35 -30
- package/dist/scheduler/ScheduleTriggerServer.d.ts.map +1 -1
- package/dist/scheduler/ScheduleTriggerServer.js +25 -27
- package/dist/scheduler/ScheduleTriggerServer.js.map +1 -1
- package/dist/scheduler/Scheduler.d.ts +5 -3
- package/dist/scheduler/Scheduler.d.ts.map +1 -1
- package/dist/scheduler/Scheduler.js +9 -6
- package/dist/scheduler/Scheduler.js.map +1 -1
- package/dist/scheduler/SlotCoordinator.d.ts +51 -20
- package/dist/scheduler/SlotCoordinator.d.ts.map +1 -1
- package/dist/scheduler/SlotCoordinator.js +98 -72
- package/dist/scheduler/SlotCoordinator.js.map +1 -1
- package/dist/storage/DatabaseMigration.d.ts.map +1 -1
- package/dist/storage/DatabaseMigration.js +42 -5
- package/dist/storage/DatabaseMigration.js.map +1 -1
- package/dist/storage/repositories/SlotRepository.d.ts +32 -8
- package/dist/storage/repositories/SlotRepository.d.ts.map +1 -1
- package/dist/storage/repositories/SlotRepository.js +69 -15
- package/dist/storage/repositories/SlotRepository.js.map +1 -1
- package/dist/webui/package.json +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Canonical Schedule Occurrence resolution.
|
|
4
|
+
*
|
|
5
|
+
* A Slot is "one durable execution occurrence of a configured Schedule" — it is
|
|
6
|
+
* NOT a morning/evening row. Identity derives from (schedule definition, the
|
|
7
|
+
* schedule's own cron + timezone, and the trigger moment): every trigger source
|
|
8
|
+
* (internal cron tick, authenticated HTTP trigger, bounded internal catch-up)
|
|
9
|
+
* resolves the SAME canonical scheduled time for a given wall-clock instant, so
|
|
10
|
+
* duplicate/concurrent/retry triggers converge on one Slot.
|
|
11
|
+
*
|
|
12
|
+
* Pure + dependency-light (cron-parser is already a production dependency).
|
|
13
|
+
* This module is the ONLY place that computes occurrence identity / due-window.
|
|
14
|
+
* Adapters (cron/http/cli) must never hand-roll slot ids or dates.
|
|
15
|
+
*/
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.scheduleTimezone = scheduleTimezone;
|
|
21
|
+
exports.resolveOccurrence = resolveOccurrence;
|
|
22
|
+
exports.checkOccurrenceWindow = checkOccurrenceWindow;
|
|
23
|
+
const cron_parser_1 = __importDefault(require("cron-parser"));
|
|
24
|
+
const DEFAULT_TZ = 'UTC';
|
|
25
|
+
/** Resolve the schedule's configured timezone (never the server's local tz). */
|
|
26
|
+
function scheduleTimezone(schedule, fallback) {
|
|
27
|
+
return schedule?.timezone?.trim() || fallback?.trim() || DEFAULT_TZ;
|
|
28
|
+
}
|
|
29
|
+
function partsInTz(date, tz) {
|
|
30
|
+
const parts = new Intl.DateTimeFormat('en-CA', {
|
|
31
|
+
timeZone: tz,
|
|
32
|
+
year: 'numeric',
|
|
33
|
+
month: '2-digit',
|
|
34
|
+
day: '2-digit',
|
|
35
|
+
}).formatToParts(date);
|
|
36
|
+
const get = (t) => parts.find((p) => p.type === t)?.value ?? '';
|
|
37
|
+
return { y: get('year'), m: get('month'), d: get('day') };
|
|
38
|
+
}
|
|
39
|
+
function hhmmInTz(date, tz) {
|
|
40
|
+
const parts = new Intl.DateTimeFormat('en-GB', {
|
|
41
|
+
timeZone: tz,
|
|
42
|
+
hour: '2-digit',
|
|
43
|
+
minute: '2-digit',
|
|
44
|
+
hour12: false,
|
|
45
|
+
}).formatToParts(date);
|
|
46
|
+
const get = (t) => parts.find((p) => p.type === t)?.value ?? '00';
|
|
47
|
+
return `${get('hour')}:${get('minute')}`;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Return the most recent scheduled fire time of `cron` at or before `at` in
|
|
51
|
+
* `tz`. This is the canonical occurrence for a trigger arriving at `at`: late
|
|
52
|
+
* triggers (watchdog/retry/wake delay) resolve to the fire they belong to.
|
|
53
|
+
*/
|
|
54
|
+
function resolveOccurrence(input) {
|
|
55
|
+
const { schedule, at = new Date(), triggerSource } = input;
|
|
56
|
+
const tz = scheduleTimezone(schedule);
|
|
57
|
+
const cronExpr = schedule.cron;
|
|
58
|
+
if (!cronExpr) {
|
|
59
|
+
throw new Error(`schedule ${schedule.id} has no cron expression; cannot resolve occurrence`);
|
|
60
|
+
}
|
|
61
|
+
// A trigger belongs to the occurrence whose window contains the trigger
|
|
62
|
+
// instant: the last fire at/before `at`, OR — when `at` is just before a fire
|
|
63
|
+
// (clock fired a hair early / a small lead) — that upcoming fire. Resolving to
|
|
64
|
+
// "yesterday's fire" for an on-time tick is what a naive prev() would do
|
|
65
|
+
// (cron-parser is exclusive of the anchor), so peek both sides and pick the
|
|
66
|
+
// occurrence whose lead/grace window actually contains `at`.
|
|
67
|
+
// cron-parser treats the anchor instant as exclusive: prev() exactly AT a
|
|
68
|
+
// fire time returns the PREVIOUS fire. Nudge the anchor a minute forward (a
|
|
69
|
+
// schedule is minute-granular) so an on-time tick resolves to its own fire,
|
|
70
|
+
// then pick prev vs the upcoming fire by window.
|
|
71
|
+
const anchor = new Date(at.getTime() + 60_000);
|
|
72
|
+
const interval = cron_parser_1.default.parseExpression(cronExpr, { currentDate: anchor, tz, iterator: false });
|
|
73
|
+
const prev = interval.prev().toDate();
|
|
74
|
+
const next = cron_parser_1.default
|
|
75
|
+
.parseExpression(cronExpr, { currentDate: at, tz, iterator: false })
|
|
76
|
+
.next()
|
|
77
|
+
.toDate();
|
|
78
|
+
// Default to the most recent fire; prefer the upcoming one only when `at` is
|
|
79
|
+
// within its lead window (a clock that fired a hair early). Lead is
|
|
80
|
+
// resolver-internal and small (15 min).
|
|
81
|
+
const LEAD_MS = 15 * 60_000;
|
|
82
|
+
const fire = next.getTime() - at.getTime() <= LEAD_MS && next.getTime() >= at.getTime() ? next : prev;
|
|
83
|
+
const { y, m, d } = partsInTz(fire, tz);
|
|
84
|
+
const occurrenceDate = `${y}-${m}-${d}`;
|
|
85
|
+
const occurrenceLabel = hhmmInTz(fire, tz);
|
|
86
|
+
// Stable, filesystem/URL-safe id: minute precision in the tz wall clock.
|
|
87
|
+
const occurrenceStamp = `${occurrenceDate}T${occurrenceLabel.replace(':', '')}`;
|
|
88
|
+
const slotId = `${schedule.id}@${occurrenceStamp}`;
|
|
89
|
+
return {
|
|
90
|
+
slotId,
|
|
91
|
+
scheduleId: schedule.id,
|
|
92
|
+
occurrenceAt: fire,
|
|
93
|
+
occurrenceAtIso: fire.toISOString(),
|
|
94
|
+
occurrenceDate,
|
|
95
|
+
occurrenceLabel,
|
|
96
|
+
timezone: tz,
|
|
97
|
+
triggerSource,
|
|
98
|
+
scheduleName: schedule.name?.trim() || schedule.id,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Validate that a trigger at `at` may run `occurrence`: it is runnable from a
|
|
103
|
+
* small lead before its scheduled time until `graceMinutes` after. Outside that
|
|
104
|
+
* window external clocks must not execute (no historical back-fill).
|
|
105
|
+
*/
|
|
106
|
+
function checkOccurrenceWindow(occurrence, at, graceMinutes, leadMinutes = 15) {
|
|
107
|
+
const sched = occurrence.occurrenceAt.getTime();
|
|
108
|
+
const leadMs = leadMinutes * 60_000;
|
|
109
|
+
const graceMs = graceMinutes * 60_000;
|
|
110
|
+
const now = at.getTime();
|
|
111
|
+
if (now < sched - leadMs) {
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
status: 425,
|
|
115
|
+
error: `schedule ${occurrence.scheduleId} occurrence ${occurrence.occurrenceAtIso} is not due yet`,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (now > sched + graceMs) {
|
|
119
|
+
return {
|
|
120
|
+
ok: false,
|
|
121
|
+
status: 410,
|
|
122
|
+
error: `schedule ${occurrence.scheduleId} occurrence ${occurrence.occurrenceAtIso} has expired (grace ${graceMinutes}m)`,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return { ok: true };
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=OccurrenceResolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OccurrenceResolver.js","sourceRoot":"","sources":["../../src/scheduler/OccurrenceResolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,44 +1,50 @@
|
|
|
1
|
+
import { SlotContext } from './SlotCoordinator';
|
|
2
|
+
import { TriggerSource } from './OccurrenceResolver';
|
|
1
3
|
/**
|
|
2
|
-
* Authenticated HTTP
|
|
4
|
+
* Authenticated HTTP schedule trigger.
|
|
3
5
|
*
|
|
4
6
|
* A dumb external clock (Cloudflare cron worker, cron-job.org, GitHub Actions)
|
|
5
|
-
* POSTs
|
|
6
|
-
* token,
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* POSTs a schedule id; this server wakes with the machine, verifies a bearer
|
|
8
|
+
* token, resolves the canonical occurrence from the schedule's OWN cron +
|
|
9
|
+
* timezone (never a client-supplied date), and runs that schedule synchronously
|
|
10
|
+
* so the open HTTP request keeps the machine active for the whole run — the
|
|
11
|
+
* request itself is the activity lease (no background fire-and-forget that lets
|
|
12
|
+
* a scale-to-zero host stop mid-run). All business state lives in the Slot
|
|
13
|
+
* ledger; the handler only authenticates, validates, resolves and delegates. It
|
|
14
|
+
* never queries Pixiv, loops targets, or touches the Slot DB itself.
|
|
15
|
+
*
|
|
16
|
+
* Mounting is independent of `schedulerRuntime.mode`: external mode mounts it as
|
|
17
|
+
* the primary clock; always-on/internal mode may also mount it for manual ops.
|
|
11
18
|
*/
|
|
12
|
-
export interface
|
|
13
|
-
/** Resolve the canonical slot for a requested name (validated to now). */
|
|
14
|
-
resolveSlot(requested: string | undefined): {
|
|
15
|
-
slotId: string;
|
|
16
|
-
slotName: string;
|
|
17
|
-
slotDate: string;
|
|
18
|
-
} | {
|
|
19
|
-
error: string;
|
|
20
|
-
status: number;
|
|
21
|
-
};
|
|
22
|
-
/** Run one schedule's slot; idempotent. Returns the schedule's slot summary. */
|
|
23
|
-
runScheduleSlot(scheduleId: string, slot: {
|
|
24
|
-
slotId: string;
|
|
25
|
-
slotName: string;
|
|
26
|
-
slotDate: string;
|
|
27
|
-
}): Promise<ScheduleSlotResult>;
|
|
28
|
-
/** List enabled schedules + today's slot status (for GET). */
|
|
29
|
-
status(): unknown;
|
|
30
|
-
}
|
|
31
|
-
export interface ScheduleSlotResult {
|
|
19
|
+
export interface TriggerRunResult {
|
|
32
20
|
scheduleId: string;
|
|
33
21
|
slotId: string;
|
|
34
22
|
status: string;
|
|
35
|
-
|
|
23
|
+
alreadyCompleted?: boolean;
|
|
24
|
+
cells?: Array<{
|
|
36
25
|
targetId: string;
|
|
37
26
|
status: string;
|
|
38
27
|
workId: string | null;
|
|
39
28
|
error?: string | null;
|
|
40
29
|
}>;
|
|
41
|
-
|
|
30
|
+
}
|
|
31
|
+
export interface TriggerHandlers {
|
|
32
|
+
/** Enabled schedule ids (for 404 on unknown / GET listing). */
|
|
33
|
+
listSchedules(): string[];
|
|
34
|
+
/**
|
|
35
|
+
* Resolve the canonical occurrence for a trigger to `scheduleId` at `at`.
|
|
36
|
+
* Returns a durable SlotContext or an HTTP error ({ status, error }).
|
|
37
|
+
*/
|
|
38
|
+
resolve(scheduleId: string, source: TriggerSource, at: Date, label?: string): {
|
|
39
|
+
context: SlotContext;
|
|
40
|
+
} | {
|
|
41
|
+
error: string;
|
|
42
|
+
status: number;
|
|
43
|
+
};
|
|
44
|
+
/** Run the schedule for a resolved occurrence; idempotent. */
|
|
45
|
+
run(scheduleId: string, context: SlotContext): Promise<TriggerRunResult>;
|
|
46
|
+
/** Read-only snapshot of a schedule's current occurrence (for GET). */
|
|
47
|
+
status(scheduleId: string): unknown;
|
|
42
48
|
}
|
|
43
49
|
export declare class ScheduleTriggerServer {
|
|
44
50
|
private readonly token;
|
|
@@ -48,7 +54,6 @@ export declare class ScheduleTriggerServer {
|
|
|
48
54
|
/** Token from config or SCHEDULER_TRIGGER_TOKEN env; empty => fail closed. */
|
|
49
55
|
static resolveToken(configured?: string): string | undefined;
|
|
50
56
|
start(host: string, port: number): void;
|
|
51
|
-
private scheduleIds;
|
|
52
57
|
private auth;
|
|
53
58
|
stop(): void;
|
|
54
59
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScheduleTriggerServer.d.ts","sourceRoot":"","sources":["../../src/scheduler/ScheduleTriggerServer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ScheduleTriggerServer.d.ts","sourceRoot":"","sources":["../../src/scheduler/ScheduleTriggerServer.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CACnG;AAED,MAAM,WAAW,eAAe;IAC9B,+DAA+D;IAC/D,aAAa,IAAI,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,GACvE;QAAE,OAAO,EAAE,WAAW,CAAA;KAAE,GACxB;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,8DAA8D;IAC9D,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACzE,uEAAuE;IACvE,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;CACrC;AAED,qBAAa,qBAAqB;IAI9B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAJ3B,OAAO,CAAC,MAAM,CAAuB;gBAGlB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,eAAe;IAG5C,8EAA8E;IAC9E,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5D,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAuDvC,OAAO,CAAC,IAAI,CAsBV;IAEF,IAAI,IAAI,IAAI;CAIb"}
|
|
@@ -25,49 +25,47 @@ class ScheduleTriggerServer {
|
|
|
25
25
|
app.get('/health', (_req, res) => {
|
|
26
26
|
res.json({ status: 'ok', service: 'pixivflow-scheduler-trigger' });
|
|
27
27
|
});
|
|
28
|
+
// Read-only: list enabled schedules + their current occurrence status.
|
|
28
29
|
app.get('/internal/schedules', this.auth, (_req, res) => {
|
|
29
|
-
|
|
30
|
+
const schedules = this.handlers.listSchedules().map((id) => this.handlers.status(id));
|
|
31
|
+
res.json({ schedules });
|
|
30
32
|
});
|
|
31
|
-
|
|
33
|
+
// Trigger one schedule by id. The server resolves the occurrence from the
|
|
34
|
+
// schedule cron; the body carries no date and cannot back-fill history.
|
|
35
|
+
app.post('/internal/schedules/:scheduleId/run', this.auth, async (req, res) => {
|
|
32
36
|
try {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
res.status(resolved.status).json({ status: 'error', error: resolved.error });
|
|
37
|
+
const scheduleId = req.params.scheduleId;
|
|
38
|
+
if (!this.handlers.listSchedules().includes(scheduleId)) {
|
|
39
|
+
res.status(404).json({ status: 'error', error: `unknown schedule: ${scheduleId}` });
|
|
37
40
|
return;
|
|
38
41
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
// Optional human label for provenance (e.g. a deploy-layer "今日早班").
|
|
43
|
+
// Bounded; never parsed; identity always derives from the cron occurrence.
|
|
44
|
+
const label = typeof req.body?.label === 'string' ? req.body.label.slice(0, 80) : undefined;
|
|
45
|
+
const resolved = this.handlers.resolve(scheduleId, 'http', new Date(), label);
|
|
46
|
+
if (!('context' in resolved)) {
|
|
47
|
+
res.status(resolved.status).json({ status: 'error', error: resolved.error });
|
|
42
48
|
return;
|
|
43
49
|
}
|
|
44
|
-
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const anyWork = results.some((r) => !r.alreadyCompleted);
|
|
51
|
-
res.json({
|
|
52
|
-
status: results.some((r) => r.status === 'partial') ? 'partial' : 'ok',
|
|
53
|
-
slot: resolved.slotId,
|
|
54
|
-
note: results.every((r) => r.alreadyCompleted) ? 'already_completed' : anyWork ? 'completed' : 'noop',
|
|
55
|
-
schedules: results,
|
|
50
|
+
const result = await this.handlers.run(scheduleId, resolved.context);
|
|
51
|
+
// alreadyCompleted => 200 with a clear note; real run => 200 completed.
|
|
52
|
+
res.status(result.alreadyCompleted ? 200 : 200).json({
|
|
53
|
+
status: result.status === 'failed' ? 'failed' : 'ok',
|
|
54
|
+
schedule: result,
|
|
55
|
+
note: result.alreadyCompleted ? 'already_completed' : 'completed',
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
catch (error) {
|
|
59
|
-
logger_1.logger.error('
|
|
60
|
-
|
|
59
|
+
logger_1.logger.error('Schedule trigger failed', { error: error instanceof Error ? error.message : String(error) });
|
|
60
|
+
// The slot ledger resumes on the next trigger; a 500 tells the clock to
|
|
61
|
+
// retry safely (idempotent — the same occurrence/ slot is reused).
|
|
62
|
+
res.status(500).json({ status: 'error', error: 'schedule run failed; the occurrence will resume on the next trigger' });
|
|
61
63
|
}
|
|
62
64
|
});
|
|
63
65
|
this.server = app.listen(port, host, () => {
|
|
64
66
|
logger_1.logger.info('Schedule trigger server listening', { host, port, auth: this.token ? 'bearer' : 'DISABLED (no token)' });
|
|
65
67
|
});
|
|
66
68
|
}
|
|
67
|
-
scheduleIds() {
|
|
68
|
-
const s = this.handlers.status();
|
|
69
|
-
return s.schedules ?? [];
|
|
70
|
-
}
|
|
71
69
|
auth = (req, res, next) => {
|
|
72
70
|
if (!this.token) {
|
|
73
71
|
// Fail closed: never allow an unauthenticated trigger in production.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScheduleTriggerServer.js","sourceRoot":"","sources":["../../src/scheduler/ScheduleTriggerServer.ts"],"names":[],"mappings":";;;;;;AAAA,sDAA8D;AAC9D,6CAA8C;AAG9C,sCAAmC;
|
|
1
|
+
{"version":3,"file":"ScheduleTriggerServer.js","sourceRoot":"","sources":["../../src/scheduler/ScheduleTriggerServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { SchedulerConfig } from '../config';
|
|
2
2
|
import { Database } from '../storage/Database';
|
|
3
|
+
import { ScheduleRunOptions } from './OccurrenceResolver';
|
|
3
4
|
/**
|
|
4
5
|
* Watchdog fallback: a schedule without an explicit `timeout` still gets this
|
|
5
6
|
* cap so a wedged download run cannot occupy the scheduler queue forever.
|
|
@@ -49,21 +50,22 @@ export declare class Scheduler {
|
|
|
49
50
|
private stopped;
|
|
50
51
|
private pending;
|
|
51
52
|
constructor(config: SchedulerConfig, database?: Database | undefined, telemetry?: JobTelemetry | undefined, scheduleId?: string, admission?: JobAdmissionController | undefined, onFailure?: ((failure: JobFailure) => Promise<void> | void) | undefined);
|
|
52
|
-
start(job: () => Promise<void>): void;
|
|
53
|
+
start(job: (options?: ScheduleRunOptions) => Promise<void>): void;
|
|
53
54
|
/**
|
|
54
55
|
* Arm the scheduler for external/manual triggers (runNow) WITHOUT registering
|
|
55
56
|
* a cron task. Used in `external` scheduler mode where an authenticated HTTP
|
|
56
57
|
* trigger — not the in-process clock — fires runs.
|
|
57
58
|
*/
|
|
58
|
-
init(job: () => Promise<void>): void;
|
|
59
|
+
init(job: (options?: ScheduleRunOptions) => Promise<void>): void;
|
|
59
60
|
private arm;
|
|
60
61
|
/**
|
|
61
62
|
* Trigger one execution immediately (external HTTP trigger / catch-up /
|
|
62
63
|
* run-once). Honors the same guards as a cron firing. Returns false when the
|
|
63
64
|
* run is not admitted (already running/pending, stopped, maxed) so callers
|
|
64
65
|
* can report idempotent "already in progress" instead of assuming a start.
|
|
66
|
+
* Fire-and-forget: the returned boolean only reports admission.
|
|
65
67
|
*/
|
|
66
|
-
runNow(): boolean;
|
|
68
|
+
runNow(triggerOptions?: ScheduleRunOptions): boolean;
|
|
67
69
|
private executeJob;
|
|
68
70
|
/**
|
|
69
71
|
* Execute the job. Item counting happens via JobTelemetry in executeJob,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/Scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"Scheduler.d.ts","sourceRoot":"","sources":["../../src/scheduler/Scheduler.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;GAGG;AACH,eAAO,MAAM,2BAA2B,QAAiB,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sFAAsF;IACtF,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACrC,+FAA+F;IAC/F,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACnD,gFAAgF;IAChF,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,8DAA8D;AAC9D,MAAM,WAAW,sBAAsB;IACrC,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;CACvD;AAED,qBAAa,SAAS;IAYlB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;IAhB7B,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,GAAG,CAAkE;IAC7E,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,mBAAmB,CAAa;IACxC,OAAO,CAAC,aAAa,CAA+B;IACpD,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,OAAO,CAAkB;gBAGd,MAAM,EAAE,eAAe,EACvB,QAAQ,CAAC,EAAE,QAAQ,YAAA,EACnB,SAAS,CAAC,EAAE,YAAY,YAAA,EACxB,UAAU,GAAE,MAAkB,EAC9B,SAAS,CAAC,EAAE,sBAAsB,YAAA,EAClC,SAAS,CAAC,GAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,aAAA;IAGrE,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC;IAIjE;;;;OAIG;IACI,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC;IAIhE,OAAO,CAAC,GAAG;IAsCX;;;;;;OAMG;IACI,MAAM,CAAC,cAAc,CAAC,EAAE,kBAAkB,GAAG,OAAO;YAO7C,UAAU;IA4NxB;;;;OAIG;YACW,mBAAmB;IAQ1B,IAAI;IAgBJ,QAAQ;;;;;;;;;CAWhB"}
|
|
@@ -70,7 +70,7 @@ class Scheduler {
|
|
|
70
70
|
});
|
|
71
71
|
if (registerCron) {
|
|
72
72
|
this.task = node_cron_1.default.schedule(this.config.cron, async () => {
|
|
73
|
-
await this.executeJob(job);
|
|
73
|
+
await this.executeJob(this.job, undefined);
|
|
74
74
|
}, {
|
|
75
75
|
timezone: this.config.timezone,
|
|
76
76
|
});
|
|
@@ -82,16 +82,19 @@ class Scheduler {
|
|
|
82
82
|
* run-once). Honors the same guards as a cron firing. Returns false when the
|
|
83
83
|
* run is not admitted (already running/pending, stopped, maxed) so callers
|
|
84
84
|
* can report idempotent "already in progress" instead of assuming a start.
|
|
85
|
+
* Fire-and-forget: the returned boolean only reports admission.
|
|
85
86
|
*/
|
|
86
|
-
runNow() {
|
|
87
|
+
runNow(triggerOptions) {
|
|
87
88
|
if (!this.job)
|
|
88
89
|
return false;
|
|
89
90
|
if (this.running || this.pending || this.stopped)
|
|
90
91
|
return false;
|
|
91
|
-
void this.executeJob(this.job);
|
|
92
|
+
void this.executeJob(this.job, triggerOptions);
|
|
92
93
|
return true;
|
|
93
94
|
}
|
|
94
|
-
async executeJob(job) {
|
|
95
|
+
async executeJob(job, triggerOptions) {
|
|
96
|
+
if (!job)
|
|
97
|
+
return;
|
|
95
98
|
// Check if already running
|
|
96
99
|
if (this.running || this.pending) {
|
|
97
100
|
logger_1.logger.warn('Skipping scheduled job because previous run is still in progress');
|
|
@@ -282,8 +285,8 @@ class Scheduler {
|
|
|
282
285
|
* which queries a durable baseline before/after the run instead of trying
|
|
283
286
|
* to intercept individual download events.
|
|
284
287
|
*/
|
|
285
|
-
async executeWithTracking(job, onItemsDownloaded) {
|
|
286
|
-
await job();
|
|
288
|
+
async executeWithTracking(job, onItemsDownloaded, triggerOptions) {
|
|
289
|
+
await job(triggerOptions);
|
|
287
290
|
}
|
|
288
291
|
stop() {
|
|
289
292
|
this.stopped = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Scheduler.js","sourceRoot":"","sources":["../../src/scheduler/Scheduler.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAgD;AAGhD,sCAAmC;AACnC,4CAAuD;
|
|
1
|
+
{"version":3,"file":"Scheduler.js","sourceRoot":"","sources":["../../src/scheduler/Scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { ScheduleConfig, StandaloneConfig, TargetConfig } from '../config';
|
|
2
2
|
import { Database } from '../storage/Database';
|
|
3
3
|
import { CellStatus, SlotItemRecord, SlotRecord, SlotStatus } from '../storage/repositories/SlotRepository';
|
|
4
|
+
import { TriggerSource } from './OccurrenceResolver';
|
|
5
|
+
/**
|
|
6
|
+
* Durable execution context attached to a run. A scheduled occurrence always
|
|
7
|
+
* has a slotId; an ad-hoc/manual run has none (it never touches the slot ledger).
|
|
8
|
+
*/
|
|
4
9
|
export interface SlotContext {
|
|
5
10
|
slotId: string;
|
|
11
|
+
scheduleId: string;
|
|
12
|
+
occurrenceAt: number;
|
|
13
|
+
occurrenceDate: string;
|
|
14
|
+
occurrenceLabel: string;
|
|
15
|
+
timezone: string;
|
|
16
|
+
triggerSource: TriggerSource;
|
|
17
|
+
/**
|
|
18
|
+
* Generic execution provenance, surfaced to delivery templates. `slotName` is
|
|
19
|
+
* an optional human label (e.g. a deploy-layer "今日早班"); it is never parsed
|
|
20
|
+
* by Core and defaults to the scheduled time label.
|
|
21
|
+
*/
|
|
6
22
|
slotName: string;
|
|
7
23
|
slotDate: string;
|
|
8
|
-
triggerSource: string;
|
|
9
24
|
}
|
|
10
25
|
export interface SlotCellSummary {
|
|
11
26
|
targetId: string;
|
|
@@ -20,40 +35,56 @@ export interface SlotRunSummary {
|
|
|
20
35
|
alreadyCompleted: boolean;
|
|
21
36
|
cells: SlotCellSummary[];
|
|
22
37
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
38
|
+
export interface SlotResolveResult {
|
|
39
|
+
context?: SlotContext;
|
|
40
|
+
error?: string;
|
|
41
|
+
status?: number;
|
|
42
|
+
}
|
|
27
43
|
/**
|
|
28
|
-
* Owns the Schedule Slot ledger for one scheduler run.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
44
|
+
* Owns the Schedule Slot ledger for one scheduler run. A Slot is one durable
|
|
45
|
+
* execution occurrence of a Schedule (NOT a morning/evening row). It ensures
|
|
46
|
+
* duplicate/concurrent/retry triggers converge on one slot, completed cells are
|
|
47
|
+
* not re-run, target membership is stable once materialized, and a selected
|
|
48
|
+
* work id stays locked across automatic retries.
|
|
49
|
+
*
|
|
50
|
+
* This class is delivery-agnostic: it knows nothing about TelePost, bots, or any
|
|
51
|
+
* hosting platform — only schedules, targets and the slot ledger.
|
|
31
52
|
*/
|
|
32
53
|
export declare class SlotCoordinator {
|
|
33
54
|
private readonly database;
|
|
34
55
|
constructor(database: Database);
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Resolve + validate the canonical occurrence for a trigger. Uses ONLY the
|
|
58
|
+
* schedule's cron + timezone and the trigger instant (never a client-supplied
|
|
59
|
+
* past date). `requestedSlotName` is an optional human label for provenance;
|
|
60
|
+
* identity always derives from the resolved canonical fire time.
|
|
61
|
+
*/
|
|
62
|
+
resolveOccurrence(schedule: ScheduleConfig, config: StandaloneConfig, triggerSource: TriggerSource, at?: Date, requestedSlotName?: string): SlotResolveResult;
|
|
63
|
+
/**
|
|
64
|
+
* Open (or resume) an occurrence and snapshot its target membership on first
|
|
65
|
+
* creation. A later config reload cannot add/remove cells for this occurrence.
|
|
66
|
+
*/
|
|
67
|
+
begin(slot: SlotContext, schedule: ScheduleConfig, targets: TargetConfig[]): {
|
|
68
|
+
slotRec: SlotRecord;
|
|
69
|
+
alreadyCompleted: boolean;
|
|
39
70
|
};
|
|
40
|
-
|
|
41
|
-
|
|
71
|
+
/**
|
|
72
|
+
* The targets that still need to run for this occurrence. Membership comes
|
|
73
|
+
* from the materialized snapshot (stable), intersected with the targets the
|
|
74
|
+
* caller currently knows about; terminal cells are skipped on resume.
|
|
75
|
+
*/
|
|
42
76
|
pendingTargets(slotId: string, targets: TargetConfig[]): {
|
|
43
77
|
target: TargetConfig;
|
|
44
78
|
cell: SlotItemRecord;
|
|
45
79
|
}[];
|
|
46
|
-
/** Open (or resume) a slot and return whether the whole slot is already done. */
|
|
47
|
-
begin(slot: SlotContext, schedule: ScheduleConfig): {
|
|
48
|
-
slotRec: SlotRecord;
|
|
49
|
-
alreadyCompleted: boolean;
|
|
50
|
-
};
|
|
51
80
|
/** Lock the selected work for a cell (first selection wins; retries keep it). */
|
|
52
81
|
lockWork(slotId: string, targetId: string, workId: string, workType: string): void;
|
|
53
82
|
/** Record a cell's terminal state from the download/delivery outcome. */
|
|
54
83
|
markCell(slotId: string, targetId: string, status: CellStatus, error?: string): void;
|
|
55
|
-
/** Roll cell results up into the slot status
|
|
84
|
+
/** Roll cell results up into the slot status (one place computes the aggregate). */
|
|
56
85
|
finish(slot: SlotContext, schedule: ScheduleConfig, targets: TargetConfig[]): SlotRunSummary;
|
|
57
86
|
completedSummary(slotId: string, schedule: ScheduleConfig): SlotRunSummary;
|
|
58
87
|
}
|
|
88
|
+
/** Resolve the timezone a schedule runs in (never the server's local tz). */
|
|
89
|
+
export declare function timezoneForSchedule(schedule: ScheduleConfig | undefined, config: StandaloneConfig): string;
|
|
59
90
|
//# sourceMappingURL=SlotCoordinator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SlotCoordinator.d.ts","sourceRoot":"","sources":["../../src/scheduler/SlotCoordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,
|
|
1
|
+
{"version":3,"file":"SlotCoordinator.d.ts","sourceRoot":"","sources":["../../src/scheduler/SlotCoordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EACL,UAAU,EACV,cAAc,EACd,UAAU,EACV,UAAU,EACX,MAAM,wCAAwC,CAAC;AAEhD,OAAO,EAEL,aAAa,EAId,MAAM,sBAAsB,CAAC;AAE9B;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,UAAU,CAAC;IACnB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,QAAQ;IAE/C;;;;;OAKG;IACH,iBAAiB,CACf,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,gBAAgB,EACxB,aAAa,EAAE,aAAa,EAC5B,EAAE,GAAE,IAAiB,EACrB,iBAAiB,CAAC,EAAE,MAAM,GACzB,iBAAiB;IAkCpB;;;OAGG;IACH,KAAK,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG;QAAE,OAAO,EAAE,UAAU,CAAC;QAAC,gBAAgB,EAAE,OAAO,CAAA;KAAE;IA6B/H;;;;OAIG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG;QAAE,MAAM,EAAE,YAAY,CAAC;QAAC,IAAI,EAAE,cAAc,CAAA;KAAE,EAAE;IAczG,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKlF,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI;IAOpF,oFAAoF;IACpF,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,cAAc;IAgC5F,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,cAAc;CAgB3E;AAED,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,EAAE,MAAM,EAAE,gBAAgB,GAAG,MAAM,CAE1G"}
|