@shivaedev/jobs 0.24.0 → 0.25.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/CHANGELOG.md +12 -0
- package/README.md +5 -5
- package/dist/server/adapters/batchClockOffset.d.ts +4 -0
- package/dist/server/adapters/batchClockOffset.d.ts.map +1 -0
- package/dist/server/adapters/batchClockOffset.js +16 -0
- package/dist/server/adapters/batchClockOffset.js.map +1 -0
- package/dist/server/definition.d.ts +1 -1
- package/dist/server/definition.d.ts.map +1 -1
- package/dist/server/definition.js +2 -3
- package/dist/server/definition.js.map +1 -1
- package/dist/server/error.d.ts +7 -7
- package/dist/server/error.d.ts.map +1 -1
- package/dist/server/error.js +6 -3
- package/dist/server/error.js.map +1 -1
- package/dist/server/internal/batchHandler.d.ts +1 -1
- package/dist/server/internal/batchHandler.d.ts.map +1 -1
- package/dist/server/internal/batchHandler.js +10 -6
- package/dist/server/internal/batchHandler.js.map +1 -1
- package/dist/server/internal/register.js +1 -1
- package/dist/server/internal/register.js.map +1 -1
- package/dist/server/internal/registerWorker.d.ts +1 -1
- package/dist/server/internal/registerWorker.d.ts.map +1 -1
- package/dist/server/internal/registerWorker.js +3 -3
- package/dist/server/internal/registerWorker.js.map +1 -1
- package/dist/server/internal/runQueueWorker.d.ts +1 -1
- package/dist/server/internal/runQueueWorker.d.ts.map +1 -1
- package/dist/server/internal/runQueueWorker.js +2 -2
- package/dist/server/internal/runQueueWorker.js.map +1 -1
- package/dist/server/internal/waitForBatchExpiry.d.ts +1 -1
- package/dist/server/internal/waitForBatchExpiry.d.ts.map +1 -1
- package/dist/server/internal/waitForBatchExpiry.js +2 -4
- package/dist/server/internal/waitForBatchExpiry.js.map +1 -1
- package/package.json +3 -3
- package/src/server/adapters/batchClockOffset.ts +17 -0
- package/src/server/definition.ts +2 -3
- package/src/server/error.ts +6 -3
- package/src/server/internal/batchHandler.ts +11 -6
- package/src/server/internal/register.ts +1 -1
- package/src/server/internal/registerWorker.ts +4 -4
- package/src/server/internal/runQueueWorker.ts +2 -2
- package/src/server/internal/waitForBatchExpiry.ts +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.0 - 2026-10-31
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Measure claimed-job expiry, remaining budgets and interrupted-batch settlement waits against PostgreSQL time, independent of the runtime clock's date.
|
|
8
|
+
- Include the original failure's tag and redacted message in settle errors.
|
|
9
|
+
|
|
10
|
+
### Breaking
|
|
11
|
+
|
|
12
|
+
- Worker clients must expose `getDb()` so jobs can read their PostgreSQL clock once per batch. Custom client factories must supply it; producer-only clients are unchanged.
|
|
13
|
+
- `jobContext(job, deadline)` now requires a deadline in runtime Clock milliseconds. Callers constructing contexts must first measure the remaining expiry against the database clock, then add that duration to the runtime Clock time.
|
|
14
|
+
|
|
3
15
|
## 0.24.0 - 2026-10-31
|
|
4
16
|
|
|
5
17
|
### Added
|
package/README.md
CHANGED
|
@@ -245,9 +245,9 @@ const IndexTitle = defineQueue({
|
|
|
245
245
|
|
|
246
246
|
`Ingest` fetches one job at a time; `IndexTitle` keeps the default batch of ten. Configure the expiry for the work's expected duration. Increasing `localConcurrency` adds batches; it does not extend any job's window.
|
|
247
247
|
|
|
248
|
-
The adapter enforces each queue or scheduled job's deadline using pg-boss's `startedOn` and `expireInSeconds`. It skips jobs whose window has already passed and interrupts a running Effect at its deadline. Expired jobs remain for pg-boss's expiry and retry engine. Interruption stops the rest of that batch, as described above.
|
|
248
|
+
The adapter enforces each queue or scheduled job's deadline using pg-boss's `startedOn` and `expireInSeconds`. It reads PostgreSQL time once per claimed batch and translates the remaining expiry to the runtime Clock, so a different runtime date does not change the budget. It skips jobs whose window has already passed and interrupts a running Effect at its deadline. Expired jobs remain for pg-boss's expiry and retry engine. Interruption stops the rest of that batch, as described above.
|
|
249
249
|
|
|
250
|
-
An interrupted batch waits for pg-boss to release its original claims before returning successfully. Settlement reads use exponential backoff from 25 ms to 500 ms between reads, with a bound of one second after the latest fetched job's deadline, including a read that never resolves. If settlement cannot be observed within that bound, the callback fails with `PgBossError` (`operation: "settle"`, with a redacted `TimeoutError`) and logs the error through the worker's captured Effect context.
|
|
250
|
+
An interrupted batch waits for pg-boss to release its original claims before returning successfully. Settlement reads use exponential backoff from 25 ms to 500 ms between reads, with a bound of one second after the latest fetched job's deadline, including a read that never resolves. If settlement cannot be observed within that bound, the callback fails with `PgBossError` (`operation: "settle"`, with a redacted `TimeoutError` and its readable tag and message) and logs the error through the worker's captured Effect context.
|
|
251
251
|
|
|
252
252
|
Queue handlers can yield `job.remainingBudget`, an `Effect.Effect<Duration.Duration>` that recomputes the time left at each read and clamps it to zero. Use it to size a downstream operation's timeout:
|
|
253
253
|
|
|
@@ -534,13 +534,13 @@ Import the module that defines the name; the package has no root entry.
|
|
|
534
534
|
|
|
535
535
|
The definition options keep the pg-boss names: `queue` uses `QueueOptions` (`Queue` except `name` and `deadLetter`, with literal `QueuePolicy` values and `maxDeferrals`), `worker` uses `WorkOptions`, and a schedule's `schedule` uses `ScheduleOptions`. A queue also requires `name` and `schema`; a schedule requires `name` and `cron`.
|
|
536
536
|
|
|
537
|
-
`Jobs.layer(options)` accepts pg-boss `ConstructorOptions` plus the adapter's own options. Custom clients must supply native `complete` and `fail` capabilities to register queue or schedule workers; missing settlement capabilities fail Layer acquisition with a registration `PgBossError`. Producer-only clients do not need
|
|
537
|
+
`Jobs.layer(options)` accepts pg-boss `ConstructorOptions` plus the adapter's own options. Custom clients must supply native `complete` and `fail` capabilities to register queue or schedule workers; missing settlement capabilities fail Layer acquisition with a registration `PgBossError`. Workers also require `getDb()` to read the PostgreSQL clock when a batch arrives. Producer-only clients do not need these capabilities. Custom clients can also supply the optional native capabilities `findJobs`, `retry`, `update`, `getDb` and `updateQueue` for lookup, retry, live counts and listings, deferral and reconciliation; a requested operation fails with `PgBossError` if its required capability is absent.
|
|
538
538
|
|
|
539
539
|
`onError` handles pg-boss client `error` events using the services captured by the Layer. Only the owning jobs service is supplied automatically; a handler using another jobs definition still requires that definition's Layer.
|
|
540
540
|
|
|
541
|
-
Worker registration always requests `includeMetadata: true`, including when `worker` supplies `includeMetadata: false`; custom clients must return pg-boss's `startedOn` metadata.
|
|
541
|
+
Worker registration always requests `includeMetadata: true`, including when `worker` supplies `includeMetadata: false`; custom clients must return pg-boss's `startedOn` metadata. Direct callers use `jobContext(job, deadline)`, where `deadline` is in runtime Clock milliseconds: measure the remaining expiry against PostgreSQL time, then add it to the runtime Clock time. Registered workers receive that translation automatically.
|
|
542
542
|
|
|
543
|
-
`PgBossError` has `operation`, optional `queue` and a `Redacted` `original`. Its message names the operation
|
|
543
|
+
`PgBossError` has `operation`, optional `queue` and a `Redacted` `original`. Its message names the operation and the queue. For `settle`, it includes the original failure's tag and message through the same redaction as stored job failures. Other operations show only the original error's class and `code`, such as a PostgreSQL SQLSTATE, because the original message can quote payloads or connection strings. A registration failure names the queue it was preparing. `PgBossPayloadError` has `direction`, `queue` and a `Redacted` `original`. Those fields distinguish the pg-boss operation from the payload boundary.
|
|
544
544
|
|
|
545
545
|
### Install, setup and limits
|
|
546
546
|
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { PgBossClient } from "#client.ts";
|
|
3
|
+
export declare const batchClockOffset: (client: PgBossClient, schema: string, name: string) => Effect.Effect<number, import("#error.ts").PgBossError, never>;
|
|
4
|
+
//# sourceMappingURL=batchClockOffset.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchClockOffset.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/batchClockOffset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI/C,eAAO,MAAM,gBAAgB,uHAW3B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Clock, Effect } from "effect";
|
|
2
|
+
import { toPgBossError } from "#error.ts";
|
|
3
|
+
import { quotedSchema } from "#internal/storedRows.ts";
|
|
4
|
+
export const batchClockOffset = Effect.fnUntraced(function* (client, schema, name) {
|
|
5
|
+
const { rows } = yield* Effect.tryPromise({
|
|
6
|
+
catch: (error) => toPgBossError("settle", error, name),
|
|
7
|
+
try: () => {
|
|
8
|
+
if (client.getDb === undefined) {
|
|
9
|
+
throw new TypeError("This pg-boss client does not expose its database clock");
|
|
10
|
+
}
|
|
11
|
+
return client.getDb().executeSql(`SELECT EXTRACT(EPOCH FROM ${quotedSchema(schema)}.job_now()) * 1000 AS now`);
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
return (yield* Clock.currentTimeMillis) - Number(rows[0].now);
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=batchClockOffset.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"batchClockOffset.js","sourceRoot":"","sources":["../../../src/server/adapters/batchClockOffset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAoB,EAAE,MAAc,EAAE,IAAY;IAC9G,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACzC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC;QACtD,GAAG,EAAE,GAAG,EAAE;YACT,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;gBAChC,MAAM,IAAI,SAAS,CAAC,wDAAwD,CAAC,CAAC;YAC/E,CAAC;YACD,OAAO,MAAM,CAAC,KAAK,EAAE,CAAC,UAAU,CAAC,6BAA6B,YAAY,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC;QAChH,CAAC;KACD,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AAC/D,CAAC,CAAC,CAAC"}
|
|
@@ -91,6 +91,6 @@ export interface DefineScheduleOptions<TName extends string> {
|
|
|
91
91
|
readonly worker?: WorkOptions;
|
|
92
92
|
}
|
|
93
93
|
export declare function defineSchedule<const TName extends string>(options: DefineScheduleOptions<TName>): ScheduleDefinition<TName>;
|
|
94
|
-
export declare function jobContext(job: Job<unknown
|
|
94
|
+
export declare function jobContext(job: Job<unknown>, deadline: number): JobContext;
|
|
95
95
|
export {};
|
|
96
96
|
//# sourceMappingURL=definition.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;;;;;
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Clock, Duration, Effect, Schema } from "effect";
|
|
2
|
-
import { deadlineOf } from "#internal/deadlineOf.ts";
|
|
3
2
|
import { maxDeferrals, nativeQueueOptions } from "#internal/definitionOptions.ts";
|
|
4
3
|
import { scheduleDefinition } from "#internal/scheduleDefinition.ts";
|
|
5
4
|
export class RetryAt extends Schema.TaggedError()("RetryAt", {
|
|
@@ -27,13 +26,13 @@ export function defineQueue(options) {
|
|
|
27
26
|
export function defineSchedule(options) {
|
|
28
27
|
return scheduleDefinition(options);
|
|
29
28
|
}
|
|
30
|
-
export function jobContext(job) {
|
|
29
|
+
export function jobContext(job, deadline) {
|
|
31
30
|
return {
|
|
32
31
|
expireInSeconds: job.expireInSeconds,
|
|
33
32
|
heartbeatSeconds: job.heartbeatSeconds,
|
|
34
33
|
id: job.id,
|
|
35
34
|
name: job.name,
|
|
36
|
-
remainingBudget: Effect.map(Clock.currentTimeMillis, (now) => Duration.millis(Math.max(0,
|
|
35
|
+
remainingBudget: Effect.map(Clock.currentTimeMillis, (now) => Duration.millis(Math.max(0, deadline - now))),
|
|
37
36
|
signal: job.signal,
|
|
38
37
|
};
|
|
39
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,OAAO,OAAQ,SAAQ,MAAM,CAAC,WAAW,EAAW,CAAC,SAAS,EAAE;IACrE,EAAE,EAAE,MAAM,CAAC,WAAW;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM;CACrB,CAAC;CAAG;AAwFL,MAAM,UAAU,WAAW,CAC1B,OAA4C;IAE5C,MAAM,UAAU,GAAqC;QACpD,IAAI,EAAE,iBAAiB;QACvB,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1D,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CACnB,MAAM,CAAC,MAAM,CAAC;YACb,IAAI,EAAE,aAAsB;YAC5B,OAAO;YACP,KAAK,EAAE,UAAU;SACjB,CAAC;QACH,YAAY,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;QACzC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC;QAC/C,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;KAC5F,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC;AAUD,MAAM,UAAU,cAAc,CAA6B,OAAqC;IAC/F,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAiB,EAAE,QAAgB;IAC7D,OAAO;QACN,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAC;QAC3G,MAAM,EAAE,GAAG,CAAC,MAAM;KAClB,CAAC;AACH,CAAC"}
|
package/dist/server/error.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Redacted } from "effect";
|
|
1
|
+
import { Cause, Redacted } from "effect";
|
|
2
2
|
export type PgBossOperation = "counts" | "deadLetteredJobs" | "enqueue" | "failedJobs" | "getJob" | "health" | "install" | "register" | "retry" | "settle" | "start" | "stop";
|
|
3
|
-
declare const PgBossError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) =>
|
|
3
|
+
declare const PgBossError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
4
4
|
readonly _tag: "PgBossError";
|
|
5
5
|
} & Readonly<A>;
|
|
6
6
|
export declare class PgBossError extends PgBossError_base<{
|
|
@@ -10,7 +10,7 @@ export declare class PgBossError extends PgBossError_base<{
|
|
|
10
10
|
}> {
|
|
11
11
|
get message(): string;
|
|
12
12
|
}
|
|
13
|
-
declare const PgBossQueueOptionsError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) =>
|
|
13
|
+
declare const PgBossQueueOptionsError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
14
14
|
readonly _tag: "PgBossQueueOptionsError";
|
|
15
15
|
} & Readonly<A>;
|
|
16
16
|
export declare class PgBossQueueOptionsError extends PgBossQueueOptionsError_base<{
|
|
@@ -19,7 +19,7 @@ export declare class PgBossQueueOptionsError extends PgBossQueueOptionsError_bas
|
|
|
19
19
|
}> {
|
|
20
20
|
get message(): string;
|
|
21
21
|
}
|
|
22
|
-
declare const PgBossQueueNamesError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) =>
|
|
22
|
+
declare const PgBossQueueNamesError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
23
23
|
readonly _tag: "PgBossQueueNamesError";
|
|
24
24
|
} & Readonly<A>;
|
|
25
25
|
export declare class PgBossQueueNamesError extends PgBossQueueNamesError_base<{
|
|
@@ -28,7 +28,7 @@ export declare class PgBossQueueNamesError extends PgBossQueueNamesError_base<{
|
|
|
28
28
|
}> {
|
|
29
29
|
get message(): string;
|
|
30
30
|
}
|
|
31
|
-
declare const PgBossClientOptionsError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) =>
|
|
31
|
+
declare const PgBossClientOptionsError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
32
32
|
readonly _tag: "PgBossClientOptionsError";
|
|
33
33
|
} & Readonly<A>;
|
|
34
34
|
export declare class PgBossClientOptionsError extends PgBossClientOptionsError_base<{
|
|
@@ -37,7 +37,7 @@ export declare class PgBossClientOptionsError extends PgBossClientOptionsError_b
|
|
|
37
37
|
}> {
|
|
38
38
|
get message(): string;
|
|
39
39
|
}
|
|
40
|
-
declare const PgBossPayloadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) =>
|
|
40
|
+
declare const PgBossPayloadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
41
41
|
readonly _tag: "PgBossPayloadError";
|
|
42
42
|
} & Readonly<A>;
|
|
43
43
|
export declare class PgBossPayloadError extends PgBossPayloadError_base<{
|
|
@@ -46,7 +46,7 @@ export declare class PgBossPayloadError extends PgBossPayloadError_base<{
|
|
|
46
46
|
readonly original: Redacted.Redacted<unknown>;
|
|
47
47
|
}> {
|
|
48
48
|
}
|
|
49
|
-
declare const PgBossTestingError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) =>
|
|
49
|
+
declare const PgBossTestingError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => Cause.YieldableError & {
|
|
50
50
|
readonly _tag: "PgBossTestingError";
|
|
51
51
|
} & Readonly<A>;
|
|
52
52
|
export declare class PgBossTestingError extends PgBossTestingError_base<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAQ,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAG/C,MAAM,MAAM,eAAe,GACxB,QAAQ,GACR,kBAAkB,GAClB,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,UAAU,GACV,OAAO,GACP,QAAQ,GACR,OAAO,GACP,MAAM,CAAC;;;;AAEV,qBAAa,WAAY,SAAQ,iBAAgC;IAChE,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;IAED,IAAa,OAAO,IAAI,MAAM,CAK7B;CACD;;;;AAUD,qBAAa,uBAAwB,SAAQ,6BAA4C;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC;CACtD,CAAC;IACD,IAAa,OAAO,IAAI,MAAM,CAE7B;CACD;;;;AAED,qBAAa,qBAAsB,SAAQ,2BAA0C;IACpF,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC,CAAC;IACD,IAAa,OAAO,IAAI,MAAM,CAE7B;CACD;;;;AAED,qBAAa,wBAAyB,SAAQ,8BAA6C;IAC1F,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,CAAC;IACD,IAAa,OAAO,IAAI,MAAM,CAE7B;CACD;;;;AAED,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC9E,QAAQ,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;CAAG;;;;AAEL,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;CAAG;AAEL,wBAAgB,aAAa,CAAC,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAMrG"}
|
package/dist/server/error.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { Data, Redacted } from "effect";
|
|
1
|
+
import { Cause, Data, Redacted } from "effect";
|
|
2
|
+
import { failureOutput } from "#internal/failureOutput.ts";
|
|
2
3
|
export class PgBossError extends Data.TaggedError("PgBossError") {
|
|
3
|
-
//
|
|
4
|
+
// Non-settlement originals can quote payloads or connection strings, so only their class and code are shown.
|
|
4
5
|
get message() {
|
|
5
6
|
const target = this.queue === undefined ? "" : ` for queue ${this.queue}`;
|
|
6
|
-
|
|
7
|
+
const original = Redacted.value(this.original);
|
|
8
|
+
const detail = this.operation === "settle" ? failureOutput(Cause.fail(original)) : undefined;
|
|
9
|
+
return `pg-boss ${this.operation}${target} failed: ${detail === undefined ? originalKind(original) : `${detail._tag}: ${detail.message}`}`;
|
|
7
10
|
}
|
|
8
11
|
}
|
|
9
12
|
function originalKind(original) {
|
package/dist/server/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAgB3D,MAAM,OAAO,WAAY,SAAQ,IAAI,CAAC,WAAW,CAAC,aAAa,CAI7D;IACD,6GAA6G;IAC7G,IAAa,OAAO;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1E,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC7F,OAAO,WAAW,IAAI,CAAC,SAAS,GAAG,MAAM,YAAY,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;IAC5I,CAAC;CACD;AAED,SAAS,YAAY,CAAC,QAAiB;IACtC,IAAI,CAAC,CAAC,QAAQ,YAAY,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,QAAQ,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;AACtG,CAAC;AAED,MAAM,OAAO,uBAAwB,SAAQ,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAGrF;IACD,IAAa,OAAO;QACnB,OAAO,SAAS,IAAI,CAAC,KAAK,0CAA0C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/F,CAAC;CACD;AAED,MAAM,OAAO,qBAAsB,SAAQ,IAAI,CAAC,WAAW,CAAC,uBAAuB,CAGjF;IACD,IAAa,OAAO;QACnB,OAAO,uDAAuD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IACtI,CAAC;CACD;AAED,MAAM,OAAO,wBAAyB,SAAQ,IAAI,CAAC,WAAW,CAAC,0BAA0B,CAGvF;IACD,IAAa,OAAO;QACnB,OAAO,yBAAyB,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,wCAAwC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IACnH,CAAC;CACD;AAED,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAI3E;CAAG;AAEL,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAI3E;CAAG;AAEL,MAAM,UAAU,aAAa,CAAC,SAA0B,EAAE,KAAc,EAAE,KAAc;IACvF,OAAO,IAAI,WAAW,CAAC;QACtB,SAAS;QACT,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,KAAK;KACL,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -2,5 +2,5 @@ import { Effect } from "effect";
|
|
|
2
2
|
import type { Job } from "pg-boss";
|
|
3
3
|
import type { PgBossClient } from "#client.ts";
|
|
4
4
|
export type PgBossRunner = <A, E>(effect: Effect.Effect<A, E>) => Promise<A>;
|
|
5
|
-
export declare function batchHandler(client: PgBossClient, name: string, run: (job: Job<unknown
|
|
5
|
+
export declare function batchHandler(client: PgBossClient, name: string, schema: string, run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown>, afterFailure?: (job: Job<unknown>) => Effect.Effect<void, unknown>): (jobs: readonly Job<unknown>[]) => Effect.Effect<void, unknown, never>;
|
|
6
6
|
//# sourceMappingURL=batchHandler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchHandler.d.ts","sourceRoot":"","sources":["../../../src/server/internal/batchHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAQ,MAAM,QAAQ,CAAC;AACpD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"batchHandler.d.ts","sourceRoot":"","sources":["../../../src/server/internal/batchHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAQ,MAAM,QAAQ,CAAC;AACpD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAuB/C,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAgB7E,wBAAgB,YAAY,CAC3B,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,EAC7E,YAAY,GAAE,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAqB,UA8BvE,SAAS,GAAG,CAAC,OAAO,CAAC,EAAE,yCAiBrC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Cause, Clock, Effect, Exit } from "effect";
|
|
2
|
+
import { batchClockOffset } from "#adapters/batchClockOffset.ts";
|
|
2
3
|
import { toPgBossError } from "#error.ts";
|
|
3
4
|
import { deadlineOf } from "#internal/deadlineOf.ts";
|
|
4
5
|
import { deferredAttempt } from "#internal/deferral.ts";
|
|
@@ -27,21 +28,22 @@ function aborted(signal) {
|
|
|
27
28
|
return Effect.sync(() => signal.removeEventListener("abort", interrupt));
|
|
28
29
|
});
|
|
29
30
|
}
|
|
30
|
-
export function batchHandler(client, name, run, afterFailure = () => Effect.void) {
|
|
31
|
+
export function batchHandler(client, name, schema, run, afterFailure = () => Effect.void) {
|
|
31
32
|
const complete = client.complete?.bind(client);
|
|
32
33
|
const fail = client.fail?.bind(client);
|
|
33
34
|
if (complete === undefined || fail === undefined) {
|
|
34
35
|
throw new TypeError("This pg-boss client does not support complete and fail");
|
|
35
36
|
}
|
|
36
|
-
const handle = Effect.fnUntraced(function* (job) {
|
|
37
|
+
const handle = Effect.fnUntraced(function* (job, offset) {
|
|
37
38
|
if (job.signal.aborted) {
|
|
38
39
|
return "interrupted";
|
|
39
40
|
}
|
|
40
|
-
const
|
|
41
|
+
const deadline = deadlineOf(job) + offset;
|
|
42
|
+
const remaining = deadline - (yield* Clock.currentTimeMillis);
|
|
41
43
|
if (remaining <= 0) {
|
|
42
44
|
return "expired";
|
|
43
45
|
}
|
|
44
|
-
const exit = yield* run(job).pipe(Effect.timeoutOrElse({ duration: remaining, orElse: () => Effect.interrupt }), Effect.raceFirst(aborted(job.signal)), Effect.exit);
|
|
46
|
+
const exit = yield* run(job, deadline).pipe(Effect.timeoutOrElse({ duration: remaining, orElse: () => Effect.interrupt }), Effect.raceFirst(aborted(job.signal)), Effect.exit);
|
|
45
47
|
if (job.signal.aborted || (Exit.isFailure(exit) && Cause.hasInterrupts(exit.cause))) {
|
|
46
48
|
return "interrupted";
|
|
47
49
|
}
|
|
@@ -52,10 +54,12 @@ export function batchHandler(client, name, run, afterFailure = () => Effect.void
|
|
|
52
54
|
return "settled";
|
|
53
55
|
});
|
|
54
56
|
return (jobs) => Effect.gen(function* () {
|
|
55
|
-
const
|
|
57
|
+
const offset = yield* batchClockOffset(client, schema, name);
|
|
58
|
+
const deadline = Math.max(...jobs.map((job) => deadlineOf(job) + offset));
|
|
59
|
+
const waitForExpiry = waitForBatchExpiry(client, name, jobs, deadline).pipe(Effect.tapError(Effect.logError));
|
|
56
60
|
let expired = false;
|
|
57
61
|
for (const job of jobs) {
|
|
58
|
-
const outcome = yield* handle(job);
|
|
62
|
+
const outcome = yield* handle(job, offset);
|
|
59
63
|
if (outcome === "interrupted") {
|
|
60
64
|
return yield* waitForExpiry;
|
|
61
65
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"batchHandler.js","sourceRoot":"","sources":["../../../src/server/internal/batchHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"batchHandler.js","sourceRoot":"","sources":["../../../src/server/internal/batchHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -47,7 +47,7 @@ const registerQueue = Effect.fnUntraced(function* (client, registration, context
|
|
|
47
47
|
if (registration._tag === "QueueDefinition") {
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
-
yield* registerWorker(client, name, queue.workerOptions, (job) => runQueueWorker(registration, job), scope, schema, queue.maxDeferrals, context, execute, graceful);
|
|
50
|
+
yield* registerWorker(client, name, queue.workerOptions, (job, deadline) => runQueueWorker(registration, job, deadline), scope, schema, queue.maxDeferrals, context, execute, graceful);
|
|
51
51
|
});
|
|
52
52
|
const registerSchedule = Effect.fnUntraced(function* (client, worker, context, scope, schema, execute, graceful) {
|
|
53
53
|
const { schedule } = worker;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,5 +2,5 @@ import { type Context, Effect, Scope } from "effect";
|
|
|
2
2
|
import type { Job, WorkOptions } from "pg-boss";
|
|
3
3
|
import type { PgBossClient } from "#client.ts";
|
|
4
4
|
import { type PgBossRunner } from "#internal/batchHandler.ts";
|
|
5
|
-
export declare const registerWorker: (client: PgBossClient, name: string, options: WorkOptions, run: (job: Job<unknown
|
|
5
|
+
export declare const registerWorker: (client: PgBossClient, name: string, options: WorkOptions, run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown, unknown>, scope: Scope.Scope, schema: string, maxDeferrals: number, context: Context.Context<unknown>, execute: PgBossRunner, graceful: boolean) => Effect.Effect<string, import("#error.ts").PgBossError, never>;
|
|
6
6
|
//# sourceMappingURL=registerWorker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerWorker.d.ts","sourceRoot":"","sources":["../../../src/server/internal/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAK5E,eAAO,MAAM,cAAc,wEAIf,GAAG,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"registerWorker.d.ts","sourceRoot":"","sources":["../../../src/server/internal/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAK5E,eAAO,MAAM,cAAc,wEAIf,GAAG,CAAC,OAAO,CAAC,YAAY,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,yMAmCrF,CAAC"}
|
|
@@ -6,15 +6,15 @@ import { retryWake } from "#internal/retryWake.ts";
|
|
|
6
6
|
import { traceJob } from "#internal/tracing.ts";
|
|
7
7
|
export const registerWorker = Effect.fnUntraced(function* (client, name, options, run, scope, schema, maxDeferrals, context, execute, graceful) {
|
|
8
8
|
const fibers = yield* Scope.fork(scope);
|
|
9
|
-
function runJob(job) {
|
|
10
|
-
return Effect.provide(traceJob(deferrableAttempt(run(job), client, schema, job, maxDeferrals), job, name), context);
|
|
9
|
+
function runJob(job, deadline) {
|
|
10
|
+
return Effect.provide(traceJob(deferrableAttempt(run(job, deadline), client, schema, job, maxDeferrals), job, name), context);
|
|
11
11
|
}
|
|
12
12
|
function afterFailure(attempt) {
|
|
13
13
|
return retryWake(client, name, attempt.id, registration).pipe(Effect.forkIn(fibers), Effect.asVoid);
|
|
14
14
|
}
|
|
15
15
|
const handle = yield* Effect.try({
|
|
16
16
|
catch: (error) => toPgBossError("register", error, name),
|
|
17
|
-
try: () => batchHandler(client, name, runJob, afterFailure),
|
|
17
|
+
try: () => batchHandler(client, name, schema, runJob, afterFailure),
|
|
18
18
|
});
|
|
19
19
|
const registration = yield* Effect.try({
|
|
20
20
|
catch: (error) => toPgBossError("register", error, name),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerWorker.js","sourceRoot":"","sources":["../../../src/server/internal/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG5D,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAqB,MAAM,2BAA2B,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACxD,MAAoB,EACpB,IAAY,EACZ,OAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"registerWorker.js","sourceRoot":"","sources":["../../../src/server/internal/registerWorker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type { Job } from "pg-boss";
|
|
3
3
|
import { type QueueWorker } from "#definition.ts";
|
|
4
|
-
export declare function runQueueWorker(worker: QueueWorker, job: Job<unknown
|
|
4
|
+
export declare function runQueueWorker(worker: QueueWorker, job: Job<unknown>, deadline: number): Effect.Effect<unknown, unknown, unknown>;
|
|
5
5
|
//# sourceMappingURL=runQueueWorker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runQueueWorker.d.ts","sourceRoot":"","sources":["../../../src/server/internal/runQueueWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI9D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"runQueueWorker.d.ts","sourceRoot":"","sources":["../../../src/server/internal/runQueueWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAI9D,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,MAAM,4CAYtF"}
|
|
@@ -2,11 +2,11 @@ import { Effect, Redacted, Schema } from "effect";
|
|
|
2
2
|
import { jobContext } from "#definition.ts";
|
|
3
3
|
import { PgBossPayloadError } from "#error.ts";
|
|
4
4
|
import { payloadOf } from "#internal/tracing.ts";
|
|
5
|
-
export function runQueueWorker(worker, job) {
|
|
5
|
+
export function runQueueWorker(worker, job, deadline) {
|
|
6
6
|
return Schema.decodeUnknownEffect(worker.queue.schema)(payloadOf(job.data)).pipe(Effect.mapError((error) => new PgBossPayloadError({
|
|
7
7
|
direction: "decode",
|
|
8
8
|
original: Redacted.make(error),
|
|
9
9
|
queue: worker.queue.name,
|
|
10
|
-
})), Effect.flatMap((payload) => worker.handler(payload, jobContext(job))));
|
|
10
|
+
})), Effect.flatMap((payload) => worker.handler(payload, jobContext(job, deadline))));
|
|
11
11
|
}
|
|
12
12
|
//# sourceMappingURL=runQueueWorker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runQueueWorker.js","sourceRoot":"","sources":["../../../src/server/internal/runQueueWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EAAE,UAAU,EAAoB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,UAAU,cAAc,CAAC,MAAmB,EAAE,GAAiB;
|
|
1
|
+
{"version":3,"file":"runQueueWorker.js","sourceRoot":"","sources":["../../../src/server/internal/runQueueWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EAAE,UAAU,EAAoB,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,UAAU,cAAc,CAAC,MAAmB,EAAE,GAAiB,EAAE,QAAgB;IACtF,OAAO,MAAM,CAAC,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAC/E,MAAM,CAAC,QAAQ,CACd,CAAC,KAAK,EAAE,EAAE,CACT,IAAI,kBAAkB,CAAC;QACtB,SAAS,EAAE,QAAQ;QACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI;KACxB,CAAC,CACH,EACD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAC/E,CAAC;AACH,CAAC"}
|
|
@@ -2,5 +2,5 @@ import { Effect } from "effect";
|
|
|
2
2
|
import type { Job } from "pg-boss";
|
|
3
3
|
import type { PgBossClient } from "#client.ts";
|
|
4
4
|
import { type PgBossError } from "#error.ts";
|
|
5
|
-
export declare function waitForBatchExpiry(client: PgBossClient, name: string, jobs: readonly Job<unknown>[]): Effect.Effect<void, PgBossError>;
|
|
5
|
+
export declare function waitForBatchExpiry(client: PgBossClient, name: string, jobs: readonly Job<unknown>[], deadline: number): Effect.Effect<void, PgBossError>;
|
|
6
6
|
//# sourceMappingURL=waitForBatchExpiry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waitForBatchExpiry.d.ts","sourceRoot":"","sources":["../../../src/server/internal/waitForBatchExpiry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"waitForBatchExpiry.d.ts","sourceRoot":"","sources":["../../../src/server/internal/waitForBatchExpiry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,WAAW,CAAC;AAE5D,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,GAAG,CAAC,OAAO,CAAC,EAAE,EAC7B,QAAQ,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAsBlC"}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import { Clock, Effect } from "effect";
|
|
2
2
|
import { toPgBossError } from "#error.ts";
|
|
3
|
-
|
|
4
|
-
export function waitForBatchExpiry(client, name, jobs) {
|
|
3
|
+
export function waitForBatchExpiry(client, name, jobs, deadline) {
|
|
5
4
|
return Effect.gen(function* () {
|
|
6
5
|
const findJobs = client.findJobs?.bind(client);
|
|
7
6
|
if (findJobs === undefined) {
|
|
8
7
|
return yield* Effect.fail(new TypeError("This pg-boss client does not support reading interrupted claims"));
|
|
9
8
|
}
|
|
10
|
-
const deadline = Math.max(0, ...jobs.map(deadlineOf)) + 1000;
|
|
11
9
|
let delay = 25;
|
|
12
10
|
const poll = Effect.gen(function* () {
|
|
13
11
|
for (const job of jobs) {
|
|
@@ -22,7 +20,7 @@ export function waitForBatchExpiry(client, name, jobs) {
|
|
|
22
20
|
}
|
|
23
21
|
}
|
|
24
22
|
});
|
|
25
|
-
return yield* poll.pipe(Effect.timeout(Math.max(0, deadline - (yield* Clock.currentTimeMillis))));
|
|
23
|
+
return yield* poll.pipe(Effect.timeout(Math.max(0, deadline + 1000 - (yield* Clock.currentTimeMillis))));
|
|
26
24
|
}).pipe(Effect.mapError((error) => toPgBossError("settle", error, name)));
|
|
27
25
|
}
|
|
28
26
|
//# sourceMappingURL=waitForBatchExpiry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"waitForBatchExpiry.js","sourceRoot":"","sources":["../../../src/server/internal/waitForBatchExpiry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGvC,OAAO,EAAoB,aAAa,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"waitForBatchExpiry.js","sourceRoot":"","sources":["../../../src/server/internal/waitForBatchExpiry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGvC,OAAO,EAAoB,aAAa,EAAE,MAAM,WAAW,CAAC;AAE5D,MAAM,UAAU,kBAAkB,CACjC,MAAoB,EACpB,IAAY,EACZ,IAA6B,EAC7B,QAAgB;IAEhB,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,iEAAiE,CAAC,CAAC,CAAC;QAC7G,CAAC;QACD,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAChC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACxB,OAAO,IAAI,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACtH,IAAI,OAAO,EAAE,KAAK,KAAK,QAAQ,IAAI,OAAO,CAAC,UAAU,KAAK,GAAG,CAAC,UAAU,EAAE,CAAC;wBAC1E,MAAM;oBACP,CAAC;oBACD,mGAAmG;oBACnG,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBAC3B,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC;gBAClC,CAAC;YACF,CAAC;QACF,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1G,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;AAC3E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/jobs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.0",
|
|
4
4
|
"description": "Effect-native jobs and lifecycle management for pg-boss",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@shivaedev/http": "0.3.1",
|
|
57
|
-
"@shivaedev/quality": "0.48.
|
|
57
|
+
"@shivaedev/quality": "0.48.2",
|
|
58
58
|
"@shivaedev/test": "0.12.0",
|
|
59
59
|
"@shivaedev/test-sql": "0.15.0",
|
|
60
|
-
"@shivaedev/test-story": "0.
|
|
60
|
+
"@shivaedev/test-story": "0.28.0",
|
|
61
61
|
"@types/node": "24.19.2",
|
|
62
62
|
"effect": "4.0.6",
|
|
63
63
|
"pg-boss": "12.38.0",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Clock, Effect } from "effect";
|
|
2
|
+
import type { PgBossClient } from "#client.ts";
|
|
3
|
+
import { toPgBossError } from "#error.ts";
|
|
4
|
+
import { quotedSchema } from "#internal/storedRows.ts";
|
|
5
|
+
|
|
6
|
+
export const batchClockOffset = Effect.fnUntraced(function* (client: PgBossClient, schema: string, name: string) {
|
|
7
|
+
const { rows } = yield* Effect.tryPromise({
|
|
8
|
+
catch: (error) => toPgBossError("settle", error, name),
|
|
9
|
+
try: () => {
|
|
10
|
+
if (client.getDb === undefined) {
|
|
11
|
+
throw new TypeError("This pg-boss client does not expose its database clock");
|
|
12
|
+
}
|
|
13
|
+
return client.getDb().executeSql(`SELECT EXTRACT(EPOCH FROM ${quotedSchema(schema)}.job_now()) * 1000 AS now`);
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
return (yield* Clock.currentTimeMillis) - Number(rows[0].now);
|
|
17
|
+
});
|
package/src/server/definition.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Clock, Duration, Effect, Schema } from "effect";
|
|
2
2
|
import type { Job, policies, Queue, ScheduleOptions, WorkOptions } from "pg-boss";
|
|
3
|
-
import { deadlineOf } from "#internal/deadlineOf.ts";
|
|
4
3
|
import { maxDeferrals, nativeQueueOptions } from "#internal/definitionOptions.ts";
|
|
5
4
|
import { scheduleDefinition } from "#internal/scheduleDefinition.ts";
|
|
6
5
|
|
|
@@ -128,13 +127,13 @@ export function defineSchedule<const TName extends string>(options: DefineSchedu
|
|
|
128
127
|
return scheduleDefinition(options);
|
|
129
128
|
}
|
|
130
129
|
|
|
131
|
-
export function jobContext(job: Job<unknown
|
|
130
|
+
export function jobContext(job: Job<unknown>, deadline: number): JobContext {
|
|
132
131
|
return {
|
|
133
132
|
expireInSeconds: job.expireInSeconds,
|
|
134
133
|
heartbeatSeconds: job.heartbeatSeconds,
|
|
135
134
|
id: job.id,
|
|
136
135
|
name: job.name,
|
|
137
|
-
remainingBudget: Effect.map(Clock.currentTimeMillis, (now) => Duration.millis(Math.max(0,
|
|
136
|
+
remainingBudget: Effect.map(Clock.currentTimeMillis, (now) => Duration.millis(Math.max(0, deadline - now))),
|
|
138
137
|
signal: job.signal,
|
|
139
138
|
};
|
|
140
139
|
}
|
package/src/server/error.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Data, Redacted } from "effect";
|
|
1
|
+
import { Cause, Data, Redacted } from "effect";
|
|
2
|
+
import { failureOutput } from "#internal/failureOutput.ts";
|
|
2
3
|
|
|
3
4
|
export type PgBossOperation =
|
|
4
5
|
| "counts"
|
|
@@ -19,10 +20,12 @@ export class PgBossError extends Data.TaggedError("PgBossError")<{
|
|
|
19
20
|
readonly queue?: string | undefined;
|
|
20
21
|
readonly original: Redacted.Redacted<unknown>;
|
|
21
22
|
}> {
|
|
22
|
-
//
|
|
23
|
+
// Non-settlement originals can quote payloads or connection strings, so only their class and code are shown.
|
|
23
24
|
override get message(): string {
|
|
24
25
|
const target = this.queue === undefined ? "" : ` for queue ${this.queue}`;
|
|
25
|
-
|
|
26
|
+
const original = Redacted.value(this.original);
|
|
27
|
+
const detail = this.operation === "settle" ? failureOutput(Cause.fail(original)) : undefined;
|
|
28
|
+
return `pg-boss ${this.operation}${target} failed: ${detail === undefined ? originalKind(original) : `${detail._tag}: ${detail.message}`}`;
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
31
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Cause, Clock, Effect, Exit } from "effect";
|
|
2
2
|
import type { Job } from "pg-boss";
|
|
3
|
+
import { batchClockOffset } from "#adapters/batchClockOffset.ts";
|
|
3
4
|
import type { PgBossClient } from "#client.ts";
|
|
4
5
|
import { toPgBossError } from "#error.ts";
|
|
5
6
|
import { deadlineOf } from "#internal/deadlineOf.ts";
|
|
@@ -42,7 +43,8 @@ function aborted(signal: AbortSignal) {
|
|
|
42
43
|
export function batchHandler(
|
|
43
44
|
client: PgBossClient,
|
|
44
45
|
name: string,
|
|
45
|
-
|
|
46
|
+
schema: string,
|
|
47
|
+
run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown>,
|
|
46
48
|
afterFailure: (job: Job<unknown>) => Effect.Effect<void, unknown> = () => Effect.void,
|
|
47
49
|
) {
|
|
48
50
|
const complete = client.complete?.bind(client);
|
|
@@ -50,15 +52,16 @@ export function batchHandler(
|
|
|
50
52
|
if (complete === undefined || fail === undefined) {
|
|
51
53
|
throw new TypeError("This pg-boss client does not support complete and fail");
|
|
52
54
|
}
|
|
53
|
-
const handle = Effect.fnUntraced(function* (job: Job<unknown
|
|
55
|
+
const handle = Effect.fnUntraced(function* (job: Job<unknown>, offset: number) {
|
|
54
56
|
if (job.signal.aborted) {
|
|
55
57
|
return "interrupted";
|
|
56
58
|
}
|
|
57
|
-
const
|
|
59
|
+
const deadline = deadlineOf(job) + offset;
|
|
60
|
+
const remaining = deadline - (yield* Clock.currentTimeMillis);
|
|
58
61
|
if (remaining <= 0) {
|
|
59
62
|
return "expired";
|
|
60
63
|
}
|
|
61
|
-
const exit = yield* run(job).pipe(
|
|
64
|
+
const exit = yield* run(job, deadline).pipe(
|
|
62
65
|
Effect.timeoutOrElse({ duration: remaining, orElse: () => Effect.interrupt }),
|
|
63
66
|
Effect.raceFirst(aborted(job.signal)),
|
|
64
67
|
Effect.exit,
|
|
@@ -74,10 +77,12 @@ export function batchHandler(
|
|
|
74
77
|
});
|
|
75
78
|
return (jobs: readonly Job<unknown>[]) =>
|
|
76
79
|
Effect.gen(function* () {
|
|
77
|
-
const
|
|
80
|
+
const offset = yield* batchClockOffset(client, schema, name);
|
|
81
|
+
const deadline = Math.max(...jobs.map((job) => deadlineOf(job) + offset));
|
|
82
|
+
const waitForExpiry = waitForBatchExpiry(client, name, jobs, deadline).pipe(Effect.tapError(Effect.logError));
|
|
78
83
|
let expired = false;
|
|
79
84
|
for (const job of jobs) {
|
|
80
|
-
const outcome = yield* handle(job);
|
|
85
|
+
const outcome = yield* handle(job, offset);
|
|
81
86
|
if (outcome === "interrupted") {
|
|
82
87
|
return yield* waitForExpiry;
|
|
83
88
|
}
|
|
@@ -11,7 +11,7 @@ export const registerWorker = Effect.fnUntraced(function* (
|
|
|
11
11
|
client: PgBossClient,
|
|
12
12
|
name: string,
|
|
13
13
|
options: WorkOptions,
|
|
14
|
-
run: (job: Job<unknown
|
|
14
|
+
run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown, unknown>,
|
|
15
15
|
scope: Scope.Scope,
|
|
16
16
|
schema: string,
|
|
17
17
|
maxDeferrals: number,
|
|
@@ -20,15 +20,15 @@ export const registerWorker = Effect.fnUntraced(function* (
|
|
|
20
20
|
graceful: boolean,
|
|
21
21
|
) {
|
|
22
22
|
const fibers = yield* Scope.fork(scope);
|
|
23
|
-
function runJob(job: Job<unknown
|
|
24
|
-
return Effect.provide(traceJob(deferrableAttempt(run(job), client, schema, job, maxDeferrals), job, name), context);
|
|
23
|
+
function runJob(job: Job<unknown>, deadline: number) {
|
|
24
|
+
return Effect.provide(traceJob(deferrableAttempt(run(job, deadline), client, schema, job, maxDeferrals), job, name), context);
|
|
25
25
|
}
|
|
26
26
|
function afterFailure(attempt: Job<unknown>) {
|
|
27
27
|
return retryWake(client, name, attempt.id, registration).pipe(Effect.forkIn(fibers), Effect.asVoid);
|
|
28
28
|
}
|
|
29
29
|
const handle = yield* Effect.try({
|
|
30
30
|
catch: (error) => toPgBossError("register", error, name),
|
|
31
|
-
try: () => batchHandler(client, name, runJob, afterFailure),
|
|
31
|
+
try: () => batchHandler(client, name, schema, runJob, afterFailure),
|
|
32
32
|
});
|
|
33
33
|
const registration: Promise<string> = yield* Effect.try({
|
|
34
34
|
catch: (error) => toPgBossError("register", error, name),
|
|
@@ -4,7 +4,7 @@ import { jobContext, type QueueWorker } from "#definition.ts";
|
|
|
4
4
|
import { PgBossPayloadError } from "#error.ts";
|
|
5
5
|
import { payloadOf } from "#internal/tracing.ts";
|
|
6
6
|
|
|
7
|
-
export function runQueueWorker(worker: QueueWorker, job: Job<unknown
|
|
7
|
+
export function runQueueWorker(worker: QueueWorker, job: Job<unknown>, deadline: number) {
|
|
8
8
|
return Schema.decodeUnknownEffect(worker.queue.schema)(payloadOf(job.data)).pipe(
|
|
9
9
|
Effect.mapError(
|
|
10
10
|
(error) =>
|
|
@@ -14,6 +14,6 @@ export function runQueueWorker(worker: QueueWorker, job: Job<unknown>) {
|
|
|
14
14
|
queue: worker.queue.name,
|
|
15
15
|
}),
|
|
16
16
|
),
|
|
17
|
-
Effect.flatMap((payload) => worker.handler(payload, jobContext(job))),
|
|
17
|
+
Effect.flatMap((payload) => worker.handler(payload, jobContext(job, deadline))),
|
|
18
18
|
);
|
|
19
19
|
}
|
|
@@ -2,15 +2,18 @@ import { Clock, Effect } from "effect";
|
|
|
2
2
|
import type { Job } from "pg-boss";
|
|
3
3
|
import type { PgBossClient } from "#client.ts";
|
|
4
4
|
import { type PgBossError, toPgBossError } from "#error.ts";
|
|
5
|
-
import { deadlineOf } from "#internal/deadlineOf.ts";
|
|
6
5
|
|
|
7
|
-
export function waitForBatchExpiry(
|
|
6
|
+
export function waitForBatchExpiry(
|
|
7
|
+
client: PgBossClient,
|
|
8
|
+
name: string,
|
|
9
|
+
jobs: readonly Job<unknown>[],
|
|
10
|
+
deadline: number,
|
|
11
|
+
): Effect.Effect<void, PgBossError> {
|
|
8
12
|
return Effect.gen(function* () {
|
|
9
13
|
const findJobs = client.findJobs?.bind(client);
|
|
10
14
|
if (findJobs === undefined) {
|
|
11
15
|
return yield* Effect.fail(new TypeError("This pg-boss client does not support reading interrupted claims"));
|
|
12
16
|
}
|
|
13
|
-
const deadline = Math.max(0, ...jobs.map(deadlineOf)) + 1000;
|
|
14
17
|
let delay = 25;
|
|
15
18
|
const poll = Effect.gen(function* () {
|
|
16
19
|
for (const job of jobs) {
|
|
@@ -25,6 +28,6 @@ export function waitForBatchExpiry(client: PgBossClient, name: string, jobs: rea
|
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
});
|
|
28
|
-
return yield* poll.pipe(Effect.timeout(Math.max(0, deadline - (yield* Clock.currentTimeMillis))));
|
|
31
|
+
return yield* poll.pipe(Effect.timeout(Math.max(0, deadline + 1000 - (yield* Clock.currentTimeMillis))));
|
|
29
32
|
}).pipe(Effect.mapError((error) => toPgBossError("settle", error, name)));
|
|
30
33
|
}
|