@workglow/postgres 0.2.37 → 0.3.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/dist/job-queue/PostgresJobStore.d.ts +14 -1
- package/dist/job-queue/PostgresJobStore.d.ts.map +1 -1
- package/dist/job-queue/PostgresQueueStorage.d.ts +24 -0
- package/dist/job-queue/PostgresQueueStorage.d.ts.map +1 -1
- package/dist/job-queue/browser.js +146 -3
- package/dist/job-queue/browser.js.map +5 -5
- package/dist/job-queue/node.js +146 -3
- package/dist/job-queue/node.js.map +5 -5
- package/dist/migrations/PostgresMigrationRunner.d.ts +5 -0
- package/dist/migrations/PostgresMigrationRunner.d.ts.map +1 -1
- package/dist/migrations/postgresQueueMigrations.d.ts.map +1 -1
- package/dist/storage/PostgresTabularStorage.d.ts +29 -0
- package/dist/storage/PostgresTabularStorage.d.ts.map +1 -1
- package/dist/storage/PostgresVectorStorage.d.ts +4 -0
- package/dist/storage/PostgresVectorStorage.d.ts.map +1 -1
- package/dist/text/PostgresFtsTextIndex.d.ts +10 -0
- package/dist/text/PostgresFtsTextIndex.d.ts.map +1 -1
- package/package.json +8 -8
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Copyright 2026 Steven Roussey <sroussey@gmail.com>
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import type { IJobStore, JobRecord, JobStatus, MessageId } from "@workglow/job-queue";
|
|
6
|
+
import type { IJobStore, JobRecord, JobStatus, JobStorageFormat, MessageId, SendOptions } from "@workglow/job-queue";
|
|
7
7
|
import type { PostgresPendingWrite } from "./PostgresMessageQueue";
|
|
8
8
|
import type { PostgresQueueStorage } from "./PostgresQueueStorage";
|
|
9
9
|
export declare class PostgresJobStore<Input, Output> implements IJobStore<Input, Output> {
|
|
@@ -25,5 +25,18 @@ export declare class PostgresJobStore<Input, Output> implements IJobStore<Input,
|
|
|
25
25
|
deleteAll(): Promise<void>;
|
|
26
26
|
abort(id: MessageId): Promise<void>;
|
|
27
27
|
saveStatus(id: MessageId, status: JobStatus): Promise<void>;
|
|
28
|
+
create(body: JobStorageFormat<Input, Output>, opts: SendOptions): Promise<MessageId>;
|
|
29
|
+
findActiveByFingerprint(fingerprint: string, queueName: string): Promise<JobRecord<Input, Output> | undefined>;
|
|
30
|
+
getMany(ids: readonly MessageId[]): Promise<readonly (JobRecord<Input, Output> | undefined)[]>;
|
|
31
|
+
completeWithResult(id: MessageId, result: Output): Promise<void>;
|
|
32
|
+
failWithError(id: MessageId, opts: {
|
|
33
|
+
readonly error?: string | null;
|
|
34
|
+
readonly errorCode?: string | null;
|
|
35
|
+
readonly abortRequested?: boolean;
|
|
36
|
+
}): Promise<void>;
|
|
37
|
+
markEnqueueDeferred(id: MessageId, opts: {
|
|
38
|
+
readonly visible_at: Date;
|
|
39
|
+
readonly errorCode: string;
|
|
40
|
+
}): Promise<void>;
|
|
28
41
|
}
|
|
29
42
|
//# sourceMappingURL=PostgresJobStore.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresJobStore.d.ts","sourceRoot":"","sources":["../../src/job-queue/PostgresJobStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"PostgresJobStore.d.ts","sourceRoot":"","sources":["../../src/job-queue/PostgresJobStore.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,SAAS,EACT,SAAS,EACT,gBAAgB,EAChB,SAAS,EACT,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAEnE,qBAAa,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAE,YAAW,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC;IAC9E,uDAAuD;IACvD,SAAgB,IAAI,EAAE,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAE1D,oEAAoE;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6C;IAErE,YACE,IAAI,EAAE,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,EACzC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC,EAIpD;IAED,GAAG,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAEhE;IAEK,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAEzF;IAED,IAAI,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAExC;IAEK,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAE5E;IAED,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAEnD;IAEK,YAAY,CAChB,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAClC,OAAO,CAAC,IAAI,CAAC,CAEf;IAEK,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI7D;IAEK,SAAS,CACb,EAAE,EAAE,SAAS,EACb,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,cAAc,EAAE,OAAO,GACtB,OAAO,CAAC,IAAI,CAAC,CAMf;IAEK,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhF;IAEK,MAAM,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzC;IAEK,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAG/B;IAEK,KAAK,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAExC;IAEK,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE;IAEK,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAYzF;IAEK,uBAAuB,CAC3B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAE/C;IAEK,OAAO,CACX,GAAG,EAAE,SAAS,SAAS,EAAE,GACxB,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CAE5D;IAEK,kBAAkB,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGrE;IAEK,aAAa,CACjB,EAAE,EAAE,SAAS,EACb,IAAI,EAAE;QACJ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;KACnC,GACA,OAAO,CAAC,IAAI,CAAC,CAGf;IAEK,mBAAmB,CACvB,EAAE,EAAE,SAAS,EACb,IAAI,EAAE;QAAE,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAC9D,OAAO,CAAC,IAAI,CAAC,CAKf;CACF"}
|
|
@@ -108,6 +108,7 @@ export declare class PostgresQueueStorage<Input, Output> implements IQueueStorag
|
|
|
108
108
|
progress?: number;
|
|
109
109
|
progress_message?: string;
|
|
110
110
|
progress_details?: Record<string, any> | null;
|
|
111
|
+
visible_at?: string | null;
|
|
111
112
|
}): Promise<void>;
|
|
112
113
|
/**
|
|
113
114
|
* Clears all jobs from the queue.
|
|
@@ -147,6 +148,29 @@ export declare class PostgresQueueStorage<Input, Output> implements IQueueStorag
|
|
|
147
148
|
* Deletes a job by its ID
|
|
148
149
|
*/
|
|
149
150
|
delete(jobId: unknown): Promise<void>;
|
|
151
|
+
/**
|
|
152
|
+
* Finds the most recent active (PENDING or PROCESSING) job with the given fingerprint in this queue.
|
|
153
|
+
* Uses the partial index idx_<table>_fingerprint_active for O(1) lookup.
|
|
154
|
+
*/
|
|
155
|
+
findActiveByFingerprint(fingerprint: string, queueName: string): Promise<JobStorageFormat<Input, Output> | undefined>;
|
|
156
|
+
/**
|
|
157
|
+
* Retrieves multiple jobs by their IDs in a single query.
|
|
158
|
+
* Returns results in the same order as the input ids array, with undefined for missing ids.
|
|
159
|
+
*/
|
|
160
|
+
getMany(ids: readonly unknown[]): Promise<Array<JobStorageFormat<Input, Output> | undefined>>;
|
|
161
|
+
/**
|
|
162
|
+
* Atomically writes output and sets status=COMPLETED.
|
|
163
|
+
*/
|
|
164
|
+
completeWithResult(id: unknown, result: Output): Promise<void>;
|
|
165
|
+
/**
|
|
166
|
+
* Atomically writes error fields and sets status=FAILED.
|
|
167
|
+
* COALESCEs preserve existing error/error_code when opts fields are absent.
|
|
168
|
+
*/
|
|
169
|
+
failWithError(id: unknown, opts: {
|
|
170
|
+
readonly error?: string | null;
|
|
171
|
+
readonly errorCode?: string | null;
|
|
172
|
+
readonly abortRequested?: boolean;
|
|
173
|
+
}): Promise<void>;
|
|
150
174
|
/**
|
|
151
175
|
* Delete jobs with a specific status older than a cutoff date
|
|
152
176
|
* @param status - Status of jobs to delete
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresQueueStorage.d.ts","sourceRoot":"","sources":["../../src/job-queue/PostgresQueueStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAmB,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAcvD,eAAO,MAAM,sBAAsB,gEAElC,CAAC;AAaF;;;GAGG;AACH,qBAAa,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAE,YAAW,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC;IAUpF,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI;IAC3B,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAVtC,SAAgB,KAAK,EAAG,SAAS,CAAU;IAC3C,oCAAoC;IACpC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IACrD,sCAAsC;IACtC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAC3E,uCAAuC;IACvC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAErC,YACqB,EAAE,EAAE,IAAI,EACR,SAAS,EAAE,MAAM,EACpC,OAAO,CAAC,EAAE,mBAAmB,EAe9B;IAED,mFAAmF;IACnF,OAAO,CAAC,sBAAsB;IAI9B,6CAA6C;IAC7C,OAAO,CAAC,oBAAoB;IAI5B;;;;OAIG;IACI,aAAa,mDAEnB;IAED;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpC;IAED;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;OAIG;IACU,GAAG,CAAC,GAAG,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"PostgresQueueStorage.d.ts","sourceRoot":"","sources":["../../src/job-queue/PostgresQueueStorage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAmB,MAAM,qBAAqB,CAAC;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,4BAA4B,CAAC;AAcvD,eAAO,MAAM,sBAAsB,gEAElC,CAAC;AAaF;;;GAGG;AACH,qBAAa,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAE,YAAW,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC;IAUpF,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,IAAI;IAC3B,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM;IAVtC,SAAgB,KAAK,EAAG,SAAS,CAAU;IAC3C,oCAAoC;IACpC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IACrD,sCAAsC;IACtC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC;IAC3E,uCAAuC;IACvC,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAErC,YACqB,EAAE,EAAE,IAAI,EACR,SAAS,EAAE,MAAM,EACpC,OAAO,CAAC,EAAE,mBAAmB,EAe9B;IAED,mFAAmF;IACnF,OAAO,CAAC,sBAAsB;IAI9B,6CAA6C;IAC7C,OAAO,CAAC,oBAAoB;IAI5B;;;;OAIG;IACI,aAAa,mDAEnB;IAED;;;;OAIG;IACU,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAEpC;IAED;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAQzB;;;;OAIG;IACU,GAAG,CAAC,GAAG,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAgFvE;IAED;;;;OAIG;IACU,GAAG,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAalF;IAED;;;;OAIG;IACU,IAAI,CACf,MAAM,GAAE,SAA6B,EACrC,GAAG,GAAE,MAAY,GAChB,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAmBjD;IAED;;;;;;;OAOG;IACU,IAAI,CACf,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC1B,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAoDtD;IAED;;;;;OAKG;IACU,WAAW,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAcjF;IAED;;;;OAIG;IACU,IAAI,CAAC,MAAM,YAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAY7D;IAED;;;;;OAKG;IACU,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EhF;IAED;;;;OAIG;IACU,QAAQ,CACnB,EAAE,EAAE,OAAO,EACX,MAAM,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,MAAM,CAAC,EAAE,SAAS,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,kBAAkB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;QAC9C,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC5B,GACA,OAAO,CAAC,IAAI,CAAC,CA6Cf;IAED;;OAEG;IACU,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAQtC;IAED;;;;OAIG;IACU,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAYhE;IAED;;;;;OAKG;IACU,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBhD;IAED;;;OAGG;IACU,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvD;IAED,uGAAuG;IAC1F,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrE;IAED;;;;OAIG;IACU,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAS3F;IAED;;OAEG;IACU,YAAY,CACvB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,CAkBf;IAED;;OAEG;IACU,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAMjD;IAED;;;OAGG;IACU,uBAAuB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAYtD;IAED;;;OAGG;IACU,OAAO,CAClB,GAAG,EAAE,SAAS,OAAO,EAAE,GACtB,OAAO,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAmB7D;IAED;;OAEG;IACU,kBAAkB,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa1E;IAED;;;OAGG;IACU,aAAa,CACxB,EAAE,EAAE,OAAO,EACX,IAAI,EAAE;QACJ,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;KACnC,GACA,OAAO,CAAC,IAAI,CAAC,CAmBf;IAED;;;;OAIG;IACU,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW3F;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACI,kBAAkB,CACvB,QAAQ,EAAE,CAAC,MAAM,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAC7D,OAAO,CAAC,EAAE,qBAAqB,GAC9B,MAAM,IAAI,CA+JZ;CACF"}
|
|
@@ -299,6 +299,42 @@ function postgresQueueMigrations(tableName, prefixes) {
|
|
|
299
299
|
ON ${tableName} (${prefixIndexPrefix}queue, status, visible_at)
|
|
300
300
|
`);
|
|
301
301
|
}
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
component,
|
|
305
|
+
version: 4,
|
|
306
|
+
description: "Add UNIQUE partial index for findActiveByFingerprint O(1) lookup + fingerprint dedup at the DB layer (H2)",
|
|
307
|
+
async up(db) {
|
|
308
|
+
await db.query(`
|
|
309
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_${tableName}_fingerprint_active
|
|
310
|
+
ON ${tableName}(${prefixIndexPrefix}queue, fingerprint)
|
|
311
|
+
WHERE status IN ('PENDING','PROCESSING')
|
|
312
|
+
`);
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
component,
|
|
317
|
+
version: 5,
|
|
318
|
+
description: "Converge idx_<table>_fingerprint_active to UNIQUE for DBs that applied the pre-edit v4 (non-unique) variant",
|
|
319
|
+
async up(db) {
|
|
320
|
+
const indexName = `idx_${tableName}_fingerprint_active`;
|
|
321
|
+
const result = await db.query(`SELECT i.indisunique
|
|
322
|
+
FROM pg_class c
|
|
323
|
+
JOIN pg_index i ON i.indexrelid = c.oid
|
|
324
|
+
JOIN pg_namespace n ON n.oid = c.relnamespace
|
|
325
|
+
WHERE c.relname = $1
|
|
326
|
+
AND n.nspname = current_schema()`, [indexName]);
|
|
327
|
+
const existing = result.rows[0];
|
|
328
|
+
if (existing && existing.indisunique) {
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
await db.query(`DROP INDEX IF EXISTS ${indexName}`);
|
|
332
|
+
await db.query(`
|
|
333
|
+
CREATE UNIQUE INDEX IF NOT EXISTS ${indexName}
|
|
334
|
+
ON ${tableName}(${prefixIndexPrefix}queue, fingerprint)
|
|
335
|
+
WHERE status IN ('PENDING','PROCESSING')
|
|
336
|
+
`);
|
|
337
|
+
}
|
|
302
338
|
}
|
|
303
339
|
];
|
|
304
340
|
}
|
|
@@ -347,7 +383,7 @@ class PostgresQueueStorage {
|
|
|
347
383
|
const now = new Date().toISOString();
|
|
348
384
|
job.queue = this.queueName;
|
|
349
385
|
job.job_run_id = job.job_run_id ?? uuid4();
|
|
350
|
-
job.fingerprint = await makeFingerprint(job.input);
|
|
386
|
+
job.fingerprint = job.fingerprint ?? await makeFingerprint(job.input);
|
|
351
387
|
job.status = JobStatus2.PENDING;
|
|
352
388
|
job.progress = 0;
|
|
353
389
|
job.progress_message = "";
|
|
@@ -389,7 +425,22 @@ class PostgresQueueStorage {
|
|
|
389
425
|
job.progress_message,
|
|
390
426
|
job.progress_details ? JSON.stringify(job.progress_details) : null
|
|
391
427
|
];
|
|
392
|
-
|
|
428
|
+
let result;
|
|
429
|
+
try {
|
|
430
|
+
result = await this.db.query(sql, params);
|
|
431
|
+
} catch (err) {
|
|
432
|
+
const e = err;
|
|
433
|
+
const isUniqueViolation = e?.code === "23505";
|
|
434
|
+
const involvesFingerprint = typeof e?.constraint === "string" ? e.constraint.includes("fingerprint") : typeof e?.message === "string" ? e.message.includes("fingerprint") : false;
|
|
435
|
+
if (isUniqueViolation && involvesFingerprint && job.fingerprint) {
|
|
436
|
+
const winner = await this.findActiveByFingerprint(job.fingerprint, this.queueName);
|
|
437
|
+
if (winner?.id != null) {
|
|
438
|
+
job.id = winner.id;
|
|
439
|
+
return winner.id;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
throw err;
|
|
443
|
+
}
|
|
393
444
|
if (!result)
|
|
394
445
|
throw new Error("Failed to add to queue");
|
|
395
446
|
job.id = result.rows[0].id;
|
|
@@ -580,6 +631,8 @@ class PostgresQueueStorage {
|
|
|
580
631
|
if ("progress_details" in fields) {
|
|
581
632
|
push("progress_details", fields.progress_details != null ? JSON.stringify(fields.progress_details) : null);
|
|
582
633
|
}
|
|
634
|
+
if ("visible_at" in fields)
|
|
635
|
+
push("visible_at", fields.visible_at ?? null);
|
|
583
636
|
if (sets.length === 0)
|
|
584
637
|
return;
|
|
585
638
|
const idParam = nextParam;
|
|
@@ -668,6 +721,66 @@ class PostgresQueueStorage {
|
|
|
668
721
|
const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(3);
|
|
669
722
|
await this.db.query(`DELETE FROM ${this.tableName} WHERE id = $1 AND queue = $2${prefixConditions}`, [jobId, this.queueName, ...prefixParams]);
|
|
670
723
|
}
|
|
724
|
+
async findActiveByFingerprint(fingerprint, queueName) {
|
|
725
|
+
const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(3);
|
|
726
|
+
const result = await this.db.query(`SELECT * FROM ${this.tableName}
|
|
727
|
+
WHERE fingerprint = $1 AND queue = $2
|
|
728
|
+
AND status IN ('PENDING','PROCESSING')${prefixConditions}
|
|
729
|
+
ORDER BY created_at DESC
|
|
730
|
+
LIMIT 1`, [fingerprint, queueName, ...prefixParams]);
|
|
731
|
+
if (!result || result.rows.length === 0)
|
|
732
|
+
return;
|
|
733
|
+
return result.rows[0];
|
|
734
|
+
}
|
|
735
|
+
async getMany(ids) {
|
|
736
|
+
if (ids.length === 0)
|
|
737
|
+
return [];
|
|
738
|
+
const numericIds = ids.map((id) => Number(id)).filter((n) => Number.isInteger(n) && n > 0);
|
|
739
|
+
if (numericIds.length === 0)
|
|
740
|
+
return ids.map(() => {
|
|
741
|
+
return;
|
|
742
|
+
});
|
|
743
|
+
const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(3);
|
|
744
|
+
const result = await this.db.query(`SELECT * FROM ${this.tableName}
|
|
745
|
+
WHERE id = ANY($1::int[]) AND queue = $2${prefixConditions}`, [numericIds, this.queueName, ...prefixParams]);
|
|
746
|
+
if (!result)
|
|
747
|
+
return ids.map(() => {
|
|
748
|
+
return;
|
|
749
|
+
});
|
|
750
|
+
const map = new Map;
|
|
751
|
+
for (const row of result.rows) {
|
|
752
|
+
map.set(Number(row.id), row);
|
|
753
|
+
}
|
|
754
|
+
return ids.map((id) => map.get(Number(id)));
|
|
755
|
+
}
|
|
756
|
+
async completeWithResult(id, result) {
|
|
757
|
+
const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(3);
|
|
758
|
+
await this.db.query(`UPDATE ${this.tableName}
|
|
759
|
+
SET output = $1,
|
|
760
|
+
status = 'COMPLETED',
|
|
761
|
+
progress = 100,
|
|
762
|
+
progress_message = '',
|
|
763
|
+
progress_details = NULL,
|
|
764
|
+
completed_at = NOW() AT TIME ZONE 'UTC'
|
|
765
|
+
WHERE id = $2 AND queue = $3${prefixConditions}`, [result != null ? JSON.stringify(result) : null, id, this.queueName, ...prefixParams]);
|
|
766
|
+
}
|
|
767
|
+
async failWithError(id, opts) {
|
|
768
|
+
const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(5);
|
|
769
|
+
await this.db.query(`UPDATE ${this.tableName}
|
|
770
|
+
SET error = COALESCE($1, error),
|
|
771
|
+
error_code = COALESCE($2, error_code),
|
|
772
|
+
abort_requested_at = CASE WHEN $3 THEN NOW() AT TIME ZONE 'UTC' ELSE abort_requested_at END,
|
|
773
|
+
status = 'FAILED',
|
|
774
|
+
completed_at = COALESCE(completed_at, NOW() AT TIME ZONE 'UTC')
|
|
775
|
+
WHERE id = $4 AND queue = $5${prefixConditions}`, [
|
|
776
|
+
"error" in opts ? opts.error ?? null : null,
|
|
777
|
+
"errorCode" in opts ? opts.errorCode ?? null : null,
|
|
778
|
+
opts.abortRequested === true,
|
|
779
|
+
id,
|
|
780
|
+
this.queueName,
|
|
781
|
+
...prefixParams
|
|
782
|
+
]);
|
|
783
|
+
}
|
|
671
784
|
async deleteJobsByStatusAndAge(status, olderThanMs) {
|
|
672
785
|
const cutoffDate = new Date(Date.now() - olderThanMs).toISOString();
|
|
673
786
|
const { conditions: prefixConditions, params: prefixParams } = this.buildPrefixWhereClause(4);
|
|
@@ -1229,6 +1342,36 @@ class PostgresJobStore {
|
|
|
1229
1342
|
async saveStatus(id, status) {
|
|
1230
1343
|
await this.core.saveStatus(id, status);
|
|
1231
1344
|
}
|
|
1345
|
+
async create(body, opts) {
|
|
1346
|
+
const enriched = {
|
|
1347
|
+
...body,
|
|
1348
|
+
fingerprint: opts.fingerprint ?? body.fingerprint,
|
|
1349
|
+
job_run_id: opts.jobRunId ?? body.job_run_id,
|
|
1350
|
+
max_attempts: opts.maxAttempts ?? body.max_attempts,
|
|
1351
|
+
deadline_at: opts.timeoutSeconds != null ? new Date(Date.now() + opts.timeoutSeconds * 1000).toISOString() : body.deadline_at
|
|
1352
|
+
};
|
|
1353
|
+
return this.core.add(enriched);
|
|
1354
|
+
}
|
|
1355
|
+
async findActiveByFingerprint(fingerprint, queueName) {
|
|
1356
|
+
return this.core.findActiveByFingerprint(fingerprint, queueName);
|
|
1357
|
+
}
|
|
1358
|
+
async getMany(ids) {
|
|
1359
|
+
return this.core.getMany(ids);
|
|
1360
|
+
}
|
|
1361
|
+
async completeWithResult(id, result) {
|
|
1362
|
+
this.pending.delete(id);
|
|
1363
|
+
await this.core.completeWithResult(id, result);
|
|
1364
|
+
}
|
|
1365
|
+
async failWithError(id, opts) {
|
|
1366
|
+
this.pending.delete(id);
|
|
1367
|
+
await this.core.failWithError(id, opts);
|
|
1368
|
+
}
|
|
1369
|
+
async markEnqueueDeferred(id, opts) {
|
|
1370
|
+
await this.core.finalize(id, {
|
|
1371
|
+
visible_at: opts.visible_at.toISOString(),
|
|
1372
|
+
error_code: opts.errorCode
|
|
1373
|
+
});
|
|
1374
|
+
}
|
|
1232
1375
|
}
|
|
1233
1376
|
// src/job-queue/createPostgresQueue.ts
|
|
1234
1377
|
function createPostgresQueue(queueName, pool, opts) {
|
|
@@ -1253,4 +1396,4 @@ export {
|
|
|
1253
1396
|
POSTGRES_QUEUE_STORAGE
|
|
1254
1397
|
};
|
|
1255
1398
|
|
|
1256
|
-
//# debugId=
|
|
1399
|
+
//# debugId=161830453993645E64756E2164756E21
|