@tribe-nest/forge 1.19.0 → 1.20.0
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/package.json +1 -1
- package/src/server/jobs.ts +30 -32
package/package.json
CHANGED
package/src/server/jobs.ts
CHANGED
|
@@ -14,21 +14,8 @@ export interface AppJobsEnv {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
interface AppJobsStub {
|
|
17
|
-
reconcile: (
|
|
18
|
-
|
|
19
|
-
appId: string,
|
|
20
|
-
desired: JobSchedule[],
|
|
21
|
-
hash: string,
|
|
22
|
-
host: string,
|
|
23
|
-
) => Promise<{ changed: boolean }>;
|
|
24
|
-
enqueue: (
|
|
25
|
-
script: string,
|
|
26
|
-
appId: string,
|
|
27
|
-
name: string,
|
|
28
|
-
payload: unknown,
|
|
29
|
-
delayMs: number,
|
|
30
|
-
host: string,
|
|
31
|
-
) => Promise<void>;
|
|
17
|
+
reconcile: (script: string, appId: string, desired: JobSchedule[], hash: string) => Promise<{ changed: boolean }>;
|
|
18
|
+
enqueue: (script: string, appId: string, name: string, payload: unknown, delayMs: number) => Promise<void>;
|
|
32
19
|
status: () => Promise<AppJobsStatus>;
|
|
33
20
|
}
|
|
34
21
|
|
|
@@ -37,23 +24,34 @@ interface AppJobsStub {
|
|
|
37
24
|
* and what happened on the LAST delivery attempt. Because jobs fail silently (no
|
|
38
25
|
* logs / dead-letter), this is how you SEE why one didn't run:
|
|
39
26
|
* - `lastDispatchAt` null while `alarmAt` is in the past → the alarm isn't firing;
|
|
40
|
-
* - `
|
|
41
|
-
* - `
|
|
42
|
-
*
|
|
27
|
+
* - `lastError` starting "runner unreachable:" → a platform-side fault, not yours;
|
|
28
|
+
* - `lastDispatchStatus` "404" + "no dispatch target" → the platform has no
|
|
29
|
+
* record of where to send your runs; republish the app;
|
|
30
|
+
* - `lastDispatchStatus` "502" → your Worker isn't deployed;
|
|
43
31
|
* - `lastDispatchStatus` "401" → your app was reached but rejected the token
|
|
44
32
|
* (the dispatch-worker's APP_SYNC_SECRET ≠ the backend JWT_SECRET);
|
|
45
|
-
* - `lastDispatchStatus` "
|
|
46
|
-
*
|
|
33
|
+
* - `lastDispatchStatus` "404" + "unknown job" → the run landed but no handler
|
|
34
|
+
* in your job map has that name.
|
|
35
|
+
*
|
|
36
|
+
* For "my one-time job never ran", read `deadLetters` first. `queueDepth` on its
|
|
37
|
+
* own tells you almost nothing: `enqueueAppJob(..., delayMs: 0)` causes the run
|
|
38
|
+
* to be dispatched and the row deleted within seconds, so depth reads 0 whether
|
|
39
|
+
* the job succeeded or was never enqueued at all. A job that keeps failing
|
|
40
|
+
* retries for ~15 minutes and then appears in `deadLetters` with its error.
|
|
47
41
|
*/
|
|
48
42
|
export interface AppJobsStatus {
|
|
49
43
|
appId: string | null;
|
|
50
|
-
/** The public host job runs are posted to. Null on apps deployed before this existed. */
|
|
51
|
-
appHost: string | null;
|
|
52
44
|
now: number;
|
|
53
45
|
alarmAt: number | null;
|
|
54
46
|
schedules: Array<{ name: string; intervalMs: number | null; cron: string | null; nextRun: number }>;
|
|
55
47
|
queueDepth: number;
|
|
48
|
+
/** Names currently queued with their next attempt time. */
|
|
49
|
+
queued: Array<{ name: string; runAt: number; attempts: number }>;
|
|
50
|
+
/** One-time jobs that exhausted their retries and were given up on, newest first. */
|
|
51
|
+
deadLetters: Array<{ name: string; attempts: number; failedAt: number; error: string | null }>;
|
|
56
52
|
lastDispatchAt: number | null;
|
|
53
|
+
/** Which job the last delivery attempt was for — all jobs share one error slot. */
|
|
54
|
+
lastDispatchJob: string | null;
|
|
57
55
|
lastDispatchScript: string | null;
|
|
58
56
|
lastDispatchStatus: string | null;
|
|
59
57
|
lastError: string | null;
|
|
@@ -87,18 +85,18 @@ export type JobHandler = (payload: unknown, env: unknown, ctx: JobContext) => Pr
|
|
|
87
85
|
export interface AppJobsConfig {
|
|
88
86
|
/** The app id (VITE_APP_ID). */
|
|
89
87
|
appId: string;
|
|
90
|
-
/** This Worker's script name in the dispatch namespace (VITE_APP_SCRIPT). */
|
|
91
|
-
script: string;
|
|
92
88
|
/** The TribeNest public API base (VITE_API_URL) — used to verify the callback token. */
|
|
93
89
|
apiUrl: string;
|
|
94
90
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
91
|
+
* @deprecated No longer needed — leave it unset in new apps.
|
|
92
|
+
*
|
|
93
|
+
* This Worker's script name in the dispatch namespace (VITE_APP_SCRIPT). Your
|
|
94
|
+
* app's address is a PLATFORM fact: it is recorded at publish and resolved by
|
|
95
|
+
* the job runtime from your `appId`, so an app no longer reports where it
|
|
96
|
+
* lives. Still accepted (and forwarded as a fallback hint) so apps published
|
|
97
|
+
* before that change keep dispatching without a rebuild.
|
|
100
98
|
*/
|
|
101
|
-
|
|
99
|
+
script?: string;
|
|
102
100
|
}
|
|
103
101
|
|
|
104
102
|
const stub = (env: AppJobsEnv, appId: string): AppJobsStub => env.JOBS.get(env.JOBS.idFromName(appId));
|
|
@@ -120,7 +118,7 @@ function scheduleHash(schedules: JobSchedule[]): string {
|
|
|
120
118
|
* one, a removed one is pruned.
|
|
121
119
|
*/
|
|
122
120
|
export async function reconcileAppJobs(env: AppJobsEnv, cfg: AppJobsConfig, schedules: JobSchedule[]): Promise<void> {
|
|
123
|
-
await stub(env, cfg.appId).reconcile(cfg.script, cfg.appId, schedules, scheduleHash(schedules)
|
|
121
|
+
await stub(env, cfg.appId).reconcile(cfg.script ?? "", cfg.appId, schedules, scheduleHash(schedules));
|
|
124
122
|
}
|
|
125
123
|
|
|
126
124
|
/** Enqueue a durable one-time job (survives redeploys, retried on failure). */
|
|
@@ -131,7 +129,7 @@ export async function enqueueAppJob(
|
|
|
131
129
|
payload?: unknown,
|
|
132
130
|
delayMs = 0,
|
|
133
131
|
): Promise<void> {
|
|
134
|
-
await stub(env, cfg.appId).enqueue(cfg.script, cfg.appId, name, payload ?? null, delayMs
|
|
132
|
+
await stub(env, cfg.appId).enqueue(cfg.script ?? "", cfg.appId, name, payload ?? null, delayMs);
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
/**
|