@shivaedev/jobs 0.29.1 → 0.29.2
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 +9 -0
- package/README.md +5 -3
- package/dist/server/adapters/clientErrorLogger.d.ts +3 -0
- package/dist/server/adapters/clientErrorLogger.d.ts.map +1 -0
- package/dist/server/adapters/clientErrorLogger.js +9 -0
- package/dist/server/adapters/clientErrorLogger.js.map +1 -0
- package/dist/server/adapters/clientErrorReporter.d.ts +1 -1
- package/dist/server/adapters/clientErrorReporter.d.ts.map +1 -1
- package/dist/server/adapters/clientErrorReporter.js +3 -3
- package/dist/server/adapters/clientErrorReporter.js.map +1 -1
- package/dist/server/adapters/registerWorker.d.ts +2 -2
- package/dist/server/adapters/registerWorker.d.ts.map +1 -1
- package/dist/server/adapters/registerWorker.js +16 -7
- package/dist/server/adapters/registerWorker.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 +3 -3
- package/dist/server/internal/batchHandler.js.map +1 -1
- package/dist/server/internal/jobControl.d.ts.map +1 -1
- package/dist/server/internal/jobControl.js +17 -5
- package/dist/server/internal/jobControl.js.map +1 -1
- package/dist/server/internal/register.d.ts +3 -2
- package/dist/server/internal/register.d.ts.map +1 -1
- package/dist/server/internal/register.js +10 -9
- package/dist/server/internal/register.js.map +1 -1
- package/dist/server/internal/registerReleasedJobs.d.ts +2 -1
- package/dist/server/internal/registerReleasedJobs.d.ts.map +1 -1
- package/dist/server/internal/registerReleasedJobs.js +3 -3
- package/dist/server/internal/registerReleasedJobs.js.map +1 -1
- package/dist/server/internal/retryWake.d.ts +1 -1
- package/dist/server/internal/retryWake.d.ts.map +1 -1
- package/dist/server/internal/retryWake.js +4 -2
- package/dist/server/internal/retryWake.js.map +1 -1
- package/dist/server/service.d.ts.map +1 -1
- package/dist/server/service.js +3 -2
- package/dist/server/service.js.map +1 -1
- package/package.json +9 -9
- package/src/server/adapters/clientErrorLogger.ts +9 -0
- package/src/server/adapters/clientErrorReporter.ts +3 -3
- package/src/server/adapters/registerWorker.ts +24 -11
- package/src/server/internal/batchHandler.ts +3 -3
- package/src/server/internal/jobControl.ts +23 -6
- package/src/server/internal/register.ts +20 -11
- package/src/server/internal/registerReleasedJobs.ts +4 -3
- package/src/server/internal/retryWake.ts +4 -2
- package/src/server/service.ts +6 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.29.2 - 2026-11-02
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Bound worker shutdown drain by `stop.timeout` (30 seconds by default). Workers drain concurrently, interrupt in-flight Effects at the timeout and log a warning for each registration that times out. Work that finishes within the timeout completes normally.
|
|
8
|
+
- Tie `onError` callbacks to the jobs Layer's lifetime. Closing the Layer interrupts pending callbacks and waits for them to end before release completes; callbacks that finish before shutdown behave as before.
|
|
9
|
+
- Redact scheduled worker logs using the same diagnostic policy as queue workers. Job details sanitize stored failure output and source failure output through the same schema as job listings, including native pg-boss timeout records.
|
|
10
|
+
- Fail the scope coordinating a worker release with the original cause when heartbeat or ownership polling retries are exhausted, and stop registered jobs workers before removing the release lease. Application-host workers can no longer keep fetching after their release coordinator fails.
|
|
11
|
+
|
|
3
12
|
## 0.29.1 - 2026-11-01
|
|
4
13
|
|
|
5
14
|
### Changed
|
package/README.md
CHANGED
|
@@ -87,6 +87,8 @@ With server's `appDatabase({ migrations: { mode: "wait", release, ... } })`, eac
|
|
|
87
87
|
|
|
88
88
|
A paused worker keeps its process registered with sql's worker release while active jobs drain, so the owning release waits for it; [sql's worker release](https://github.com/ShivaeDev/platform/blob/main/packages/sql/README.md) owns the heartbeat and how long a crashed worker can block. Closing the jobs Layer's scope waits for the native pg-boss `stop` before releasing the services the Layer captured. Choose the three bounds together: each queue's `expireInSeconds`, a `stop: { graceful: true, timeout }` in milliseconds that covers it, and a host termination grace beyond that timeout. For example, a queue with `expireInSeconds: 60` pairs with `stop: { graceful: true, timeout: 65_000 }` under a 75-second termination grace.
|
|
89
89
|
|
|
90
|
+
Worker registrations drain concurrently when their Layer closes. `stop.timeout` bounds each drain in milliseconds, defaulting to 30 seconds. Work that finishes within that budget completes normally. At the timeout, the adapter logs a warning naming the queue and interrupts its in-flight Effect fibers before releasing their services. `stop.graceful: false` interrupts without waiting for drain. Keep handlers interruptible, as described under [batch expiry](#size-batches-against-expiry). The drain budget does not bound PostgreSQL disconnect acknowledgements; shutdown still waits for the pool to close.
|
|
91
|
+
|
|
90
92
|
`installPgBossSchema` installs or upgrades pg-boss through the provided Effect SQL client without starting workers or schedules. Run it outside an application transaction, in a release step or the `fixtures` Effect of `makePostgresTestLayer`, so stories inherit the schema from the migrated template:
|
|
91
93
|
|
|
92
94
|
```ts
|
|
@@ -192,7 +194,7 @@ const Compare = defineQueue({
|
|
|
192
194
|
|
|
193
195
|
This worker runs up to five handlers at once. `worker` accepts pg-boss 12's `WorkOptions`, including `batchSize`, `localConcurrency`, `pollingIntervalSeconds`, `notifyPollingIntervalSeconds` and the burst options. Explicit options override the adapter defaults. pg-boss ignores `burstWhenBatchFull` at `batchSize: 1`; keep a batch size of at least two for immediate backlog draining. Each job is settled separately through pg-boss: success completes that job, and a typed failure, payload decoding failure or defect fails only that job with its own error. A failed job does not spend the retries of other jobs in its batch or rerun their successful handlers. Interruption stops the batch and leaves the interrupted and remaining jobs to pg-boss expiry; handlers must still tolerate repeated side effects across retries and interrupted attempts.
|
|
194
196
|
|
|
195
|
-
Apps do not need to shorten the polling backstop to drain a backlog. With `notify: true` and an active LISTEN/NOTIFY listener, pg-boss wakes workers on notifications and defaults to a 30-second backstop (`notifyPollingIntervalSeconds`). Without active notifications its base poll defaults to two seconds (`pollingIntervalSeconds`). Bursting takes precedence over both intervals. After an adapter worker fails a job, it reads pg-boss's stored retry time and schedules a wake for every native worker in its registration at that time, so an idle sibling can retry while another worker is busy. The wake, including its retry-time read, belongs to the worker Layer's scope and is canceled when that scope closes. Wake failures are logged with redacted diagnostics and do not fail the batch. Override the backstop when the application needs a different bound for other work that becomes runnable without a notification, such as delayed jobs or retries initiated outside the adapter worker.
|
|
197
|
+
Apps do not need to shorten the polling backstop to drain a backlog. With `notify: true` and an active LISTEN/NOTIFY listener, pg-boss wakes workers on notifications and defaults to a 30-second backstop (`notifyPollingIntervalSeconds`). Without active notifications its base poll defaults to two seconds (`pollingIntervalSeconds`). Bursting takes precedence over both intervals. After an adapter worker fails or defers a job, it reads pg-boss's stored retry time and schedules a wake for every native worker in its registration at that time, so an idle sibling can retry while another worker is busy. The wake accounts for differences between the runtime and PostgreSQL clocks. The wake, including its retry-time read, belongs to the worker Layer's scope and is canceled when that scope closes. Wake failures are logged with redacted diagnostics and do not fail the batch. Override the backstop when the application needs a different bound for other work that becomes runnable without a notification, such as delayed jobs or retries initiated outside the adapter worker.
|
|
196
198
|
|
|
197
199
|
### Defer until a provider is ready
|
|
198
200
|
|
|
@@ -210,7 +212,7 @@ const waitForQuota = Effect.fail(
|
|
|
210
212
|
);
|
|
211
213
|
```
|
|
212
214
|
|
|
213
|
-
The same job returns to waiting with `startAfter` set to `at`; its ID, singleton key, payload and retry count stay unchanged. A past or current `at` is eligible on the next fetch. Deferral does not dead-letter the job or call `onError`. Its job span ends OK with a `job.deferred` event whose `at` is an ISO UTC string and whose `reason` is the supplied string.
|
|
215
|
+
The same job returns to waiting with `startAfter` set to `at`; its ID, singleton key, payload and retry count stay unchanged. A past or current `at` is eligible on the next fetch. Deferral does not dead-letter the job or call `onError`. Its job span ends OK with a `job.deferred` event whose `at` is an ISO UTC string and whose `reason` is the supplied string. The adapter wakes workers in the same registration when the deferral becomes due, including queues using `notify: true`, so they can resume the job without waiting for the polling backstop. Stately jobs sharing a singleton key can defer together and still run one at a time. While waiting, their native job metadata reports the adapter's `effect-stately-deferred` policy; a database trigger restores `stately` when pg-boss claims them, preserving its active-job exclusion.
|
|
214
216
|
|
|
215
217
|
Set `queue: { maxDeferrals: 20 }` on a queue or schedule to change the default limit of ten deferrals per job. The limit must be a nonnegative safe integer; zero disables deferral. Once the limit is reached, `RetryAt` follows the normal failure and retry path. The adapter stores the count in its own table in the pg-boss schema, preserving it across worker restarts, ordinary failures, expiry and heartbeat timeouts. Queue handlers read this table before every attempt, including handlers that never defer. Automatic migrations and `installPgBossSchema` create this table and the stately claim trigger; use `installPgBossSchema` or the `pgBossSchema` migration component before starting workers with `migrate: false`.
|
|
216
218
|
|
|
@@ -567,7 +569,7 @@ The definition options keep the pg-boss names: `queue` uses `QueueOptions` (`Que
|
|
|
567
569
|
|
|
568
570
|
`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.
|
|
569
571
|
|
|
570
|
-
`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.
|
|
572
|
+
`onError` handles pg-boss client `error` events using the services captured by the Layer. The Layer interrupts pending callbacks and waits for them to end before release completes. Only the owning jobs service is supplied automatically; a handler using another jobs definition still requires that definition's Layer.
|
|
571
573
|
|
|
572
574
|
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.
|
|
573
575
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientErrorLogger.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/clientErrorLogger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,eAAO,MAAM,iBAAiB,8BAEd,KAAK,KAAG,IAAI,eAG1B,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { logClientError } from "#internal/clientErrors.ts";
|
|
3
|
+
export const clientErrorLogger = Effect.fnUntraced(function* () {
|
|
4
|
+
const run = Effect.runForkWith(yield* Effect.context());
|
|
5
|
+
return (error) => {
|
|
6
|
+
run(Effect.exit(logClientError(error)));
|
|
7
|
+
};
|
|
8
|
+
});
|
|
9
|
+
//# sourceMappingURL=clientErrorLogger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clientErrorLogger.js","sourceRoot":"","sources":["../../../src/server/adapters/clientErrorLogger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;IAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,EAAS,CAAC,CAAC;IAC/D,OAAO,CAAC,KAAY,EAAQ,EAAE;QAC7B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
|
-
export declare const clientErrorReporter: <R>(report: (error: Error) => Effect.Effect<unknown, never, R>) => Effect.Effect<(error: Error) => void, never, R>;
|
|
2
|
+
export declare const clientErrorReporter: <R>(report: (error: Error) => Effect.Effect<unknown, never, R>) => Effect.Effect<(error: Error) => void, never, R | import("effect/Scope").Scope>;
|
|
3
3
|
//# sourceMappingURL=clientErrorReporter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientErrorReporter.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/clientErrorReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"clientErrorReporter.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/clientErrorReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,QAAQ,CAAC;AAE1C,eAAO,MAAM,mBAAmB,GAAgC,CAAC,kBAAkB,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,2BAE7G,KAAK,KAAG,IAAI,0CAG1B,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
1
|
+
import { Effect, FiberSet } from "effect";
|
|
2
2
|
export const clientErrorReporter = Effect.fnUntraced(function* (report) {
|
|
3
|
-
const run =
|
|
3
|
+
const run = yield* FiberSet.makeRuntime();
|
|
4
4
|
return (error) => {
|
|
5
|
-
|
|
5
|
+
run(Effect.exit(Effect.suspend(() => report(error))));
|
|
6
6
|
};
|
|
7
7
|
});
|
|
8
8
|
//# sourceMappingURL=clientErrorReporter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientErrorReporter.js","sourceRoot":"","sources":["../../../src/server/adapters/clientErrorReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"clientErrorReporter.js","sourceRoot":"","sources":["../../../src/server/adapters/clientErrorReporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAK,MAA0D;IAC5H,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAK,CAAC;IAC7C,OAAO,CAAC,KAAY,EAAQ,EAAE;QAC7B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect, Scope } from "effect";
|
|
2
|
-
import type { Job, WorkOptions } from "pg-boss";
|
|
2
|
+
import type { Job, StopOptions, WorkOptions } from "pg-boss";
|
|
3
3
|
import type { PgBossClient } from "#client.ts";
|
|
4
|
-
export declare const registerWorker: <R>(client: PgBossClient, name: string, options: WorkOptions, run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown, R>, scope: Scope.Scope, schema: string, maxDeferrals: number,
|
|
4
|
+
export declare const registerWorker: <R>(client: PgBossClient, name: string, options: WorkOptions, run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown, R>, scope: Scope.Scope, schema: string, maxDeferrals: number, stop?: StopOptions | undefined) => Effect.Effect<string, import("#error.ts").PgBossError, R>;
|
|
5
5
|
//# sourceMappingURL=registerWorker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerWorker.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"registerWorker.d.ts","sourceRoot":"","sources":["../../../src/server/adapters/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAS,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C,eAAO,MAAM,cAAc,GAAgC,CAAC,uEAIhD,GAAG,CAAC,OAAO,CAAC,YAAY,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,wJA+C/E,CAAC"}
|
|
@@ -4,28 +4,37 @@ import { batchHandler } from "#internal/batchHandler.ts";
|
|
|
4
4
|
import { deferrableAttempt } from "#internal/deferrableAttempt.ts";
|
|
5
5
|
import { retryWake } from "#internal/retryWake.ts";
|
|
6
6
|
import { traceJob } from "#internal/tracing.ts";
|
|
7
|
-
export const registerWorker = Effect.fnUntraced(function* (client, name, options, run, scope, schema, maxDeferrals,
|
|
7
|
+
export const registerWorker = Effect.fnUntraced(function* (client, name, options, run, scope, schema, maxDeferrals, stop) {
|
|
8
8
|
const execute = Effect.runPromiseWith(yield* Effect.context());
|
|
9
|
-
const
|
|
9
|
+
const workerScope = yield* Scope.fork(scope);
|
|
10
|
+
const fibers = yield* Scope.fork(workerScope);
|
|
10
11
|
function runJob(job, deadline) {
|
|
11
12
|
return traceJob(deferrableAttempt(run(job, deadline), client, schema, job, maxDeferrals), job, name);
|
|
12
13
|
}
|
|
13
|
-
function
|
|
14
|
-
return retryWake(client, name, attempt.id, registration).pipe(Effect.forkIn(fibers), Effect.asVoid);
|
|
14
|
+
function afterRetry(attempt) {
|
|
15
|
+
return retryWake(client, schema, name, attempt.id, registration).pipe(Effect.forkIn(fibers), Effect.asVoid);
|
|
15
16
|
}
|
|
16
17
|
const handle = yield* Effect.try({
|
|
17
18
|
catch: (error) => toPgBossError("register", error, name),
|
|
18
|
-
try: () => batchHandler(client, name, schema, runJob,
|
|
19
|
+
try: () => batchHandler(client, name, schema, runJob, afterRetry),
|
|
19
20
|
});
|
|
20
21
|
const registration = yield* Effect.try({
|
|
21
22
|
catch: (error) => toPgBossError("register", error, name),
|
|
22
23
|
try: () => client.work(name, { ...options, includeMetadata: true }, (jobs) => execute(handle(jobs).pipe(Effect.forkIn(fibers), Effect.flatMap(Fiber.join)))),
|
|
23
24
|
});
|
|
24
25
|
const id = yield* Effect.tryPromise({ catch: (error) => toPgBossError("register", error, name), try: () => registration });
|
|
25
|
-
|
|
26
|
+
const graceful = stop?.graceful !== false;
|
|
27
|
+
const timeout = stop?.timeout ?? 30_000;
|
|
28
|
+
const drain = Effect.tryPromise({
|
|
26
29
|
catch: (error) => toPgBossError("stop", error, name),
|
|
27
30
|
try: () => client.offWork(name, { id, wait: graceful }),
|
|
28
|
-
})
|
|
31
|
+
});
|
|
32
|
+
yield* Scope.addFinalizer(workerScope, (graceful
|
|
33
|
+
? drain.pipe(Effect.timeoutOrElse({
|
|
34
|
+
duration: timeout,
|
|
35
|
+
orElse: () => Effect.logWarning(`pg-boss worker drain timed out for queue ${name} after ${timeout}ms; interrupting in-flight work`),
|
|
36
|
+
}), Effect.interruptible)
|
|
37
|
+
: drain).pipe(Effect.catch(Effect.logError)));
|
|
29
38
|
return id;
|
|
30
39
|
});
|
|
31
40
|
//# sourceMappingURL=registerWorker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerWorker.js","sourceRoot":"","sources":["../../../src/server/adapters/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,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,GAAgF,EAChF,KAAkB,EAClB,MAAc,EACd,YAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"registerWorker.js","sourceRoot":"","sources":["../../../src/server/adapters/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 { PgBossClient } from "#client.ts";
|
|
4
|
-
export declare function batchHandler<R>(client: PgBossClient, name: string, schema: string, run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown, R>,
|
|
4
|
+
export declare function batchHandler<R>(client: PgBossClient, name: string, schema: string, run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown, R>, afterRetry?: (job: Job<unknown>) => Effect.Effect<void, unknown>): (jobs: readonly Job<unknown>[]) => Effect.Effect<void, unknown, R>;
|
|
5
5
|
//# 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;AAEnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AA8C/C,wBAAgB,YAAY,CAAC,CAAC,EAC7B,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,EAAE,CAAC,CAAC,EAChF,
|
|
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;AA8C/C,wBAAgB,YAAY,CAAC,CAAC,EAC7B,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,EAAE,CAAC,CAAC,EAChF,UAAU,GAAE,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAqB,UA0BrE,SAAS,GAAG,CAAC,OAAO,CAAC,EAAE,qCAiBrC"}
|
|
@@ -36,7 +36,7 @@ function aborted(signal) {
|
|
|
36
36
|
return Effect.sync(() => signal.removeEventListener("abort", interrupt));
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
|
-
export function batchHandler(client, name, schema, run,
|
|
39
|
+
export function batchHandler(client, name, schema, run, afterRetry = () => Effect.void) {
|
|
40
40
|
const complete = client.complete?.bind(client);
|
|
41
41
|
const fail = client.fail?.bind(client);
|
|
42
42
|
if (complete === undefined || fail === undefined) {
|
|
@@ -56,8 +56,8 @@ export function batchHandler(client, name, schema, run, afterFailure = () => Eff
|
|
|
56
56
|
return "interrupted";
|
|
57
57
|
}
|
|
58
58
|
yield* settleAttempt(complete, fail, name, job, exit);
|
|
59
|
-
if (Exit.isFailure(exit)) {
|
|
60
|
-
yield*
|
|
59
|
+
if (Exit.isFailure(exit) || exit.value === deferredAttempt) {
|
|
60
|
+
yield* afterRetry(job);
|
|
61
61
|
}
|
|
62
62
|
return "settled";
|
|
63
63
|
});
|
|
@@ -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;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,SAAS,aAAa,CACrB,QAA+C,EAC/C,IAAuC,EACvC,IAAY,EACZ,GAAiB,EACjB,IAAiC;IAEjC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,eAAe,EAAE,CAAC;QAC5D,OAAO,MAAM,CAAC,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,MAAM,CAAC,UAAU,CAAC;QACxB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC;QACtD,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;KACpG,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,QAAgB;IAChE,IAAI,SAAS,GAAG,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAC5D,OAAO,SAAS,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC/B,SAAS,GAAG,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,SAAS,OAAO,CAAC,MAAmB;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAQ,CAAC,MAAM,EAAE,EAAE;QACxC,SAAS,SAAS;YACjB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,SAAS,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAC3B,MAAoB,EACpB,IAAY,EACZ,MAAc,EACd,GAAgF,EAChF,
|
|
1
|
+
{"version":3,"file":"batchHandler.js","sourceRoot":"","sources":["../../../src/server/internal/batchHandler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jobControl.d.ts","sourceRoot":"","sources":["../../../src/server/internal/jobControl.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"jobControl.d.ts","sourceRoot":"","sources":["../../../src/server/internal/jobControl.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWjD,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC,QAAQ,CAAC,CAuBvE;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,aAAa,CAAC,OAAO,CAAC,CAkBrE"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
import { Effect, Option } from "effect";
|
|
1
|
+
import { Effect, Option, Redacted, Schema } from "effect";
|
|
2
2
|
import { redact } from "@shivaedev/errors/redact.ts";
|
|
3
|
-
import { toPgBossError } from "#error.ts";
|
|
3
|
+
import { PgBossPayloadError, toPgBossError } from "#error.ts";
|
|
4
|
+
import { deferralOf } from "#internal/deferral.ts";
|
|
4
5
|
import { decodeStoredData } from "#internal/storedRows.ts";
|
|
6
|
+
import { JobFailure } from "#JobFailure.ts";
|
|
7
|
+
const StoredFailure = Schema.Union([JobFailure, Schema.Struct({ value: JobFailure })]);
|
|
8
|
+
function decodeFailure(queue, output) {
|
|
9
|
+
return Schema.decodeUnknownEffect(StoredFailure)(output).pipe(Effect.map((failure) => ("value" in failure ? failure.value : failure)), Effect.mapError((error) => new PgBossPayloadError({ direction: "decode", original: Redacted.make(error), queue })));
|
|
10
|
+
}
|
|
5
11
|
export function getJobFor(client) {
|
|
6
12
|
return (queue, id) => Effect.tryPromise({
|
|
7
13
|
catch: (error) => toPgBossError("getJob", error, queue.name),
|
|
@@ -11,9 +17,15 @@ export function getJobFor(client) {
|
|
|
11
17
|
}
|
|
12
18
|
return (await client.findJobs(queue.name, { id }))[0];
|
|
13
19
|
},
|
|
14
|
-
}).pipe(Effect.flatMap((job)
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
}).pipe(Effect.flatMap(Effect.fnUntraced(function* (job) {
|
|
21
|
+
if (job === undefined) {
|
|
22
|
+
return Option.none();
|
|
23
|
+
}
|
|
24
|
+
const data = yield* decodeStoredData(queue, job.data);
|
|
25
|
+
const output = job.output === null || deferralOf(job) !== undefined ? job.output : yield* decodeFailure(queue.name, job.output);
|
|
26
|
+
const sourceOutput = job.sourceOutput === null ? null : yield* decodeFailure(queue.name, job.sourceOutput);
|
|
27
|
+
return Option.some({ ...job, data: redact(data), output, sourceOutput });
|
|
28
|
+
})));
|
|
17
29
|
}
|
|
18
30
|
export function retryFor(client) {
|
|
19
31
|
return (queue, id) => Effect.tryPromise({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jobControl.js","sourceRoot":"","sources":["../../../src/server/internal/jobControl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"jobControl.js","sourceRoot":"","sources":["../../../src/server/internal/jobControl.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { type Context, Effect,
|
|
1
|
+
import { type Context, Effect, Scope } from "effect";
|
|
2
|
+
import type { StopOptions } from "pg-boss";
|
|
2
3
|
import type { PgBossClient } from "#client.ts";
|
|
3
4
|
import type { JobRegistration } from "#definition.ts";
|
|
4
5
|
import { PgBossQueueOptionsError } from "#error.ts";
|
|
5
6
|
export declare function registrationName(registration: JobRegistration): string;
|
|
6
7
|
export declare function registrationNames(registrations: readonly JobRegistration[]): readonly string[];
|
|
7
|
-
export declare const registerJobs: <R>(client: PgBossClient, registrations: readonly JobRegistration[], context: Context.Context<R>, replaceWorkers: boolean, schema?: string | undefined, startWorkers?: boolean | undefined,
|
|
8
|
+
export declare const registerJobs: <R>(client: PgBossClient, registrations: readonly JobRegistration[], context: Context.Context<R>, replaceWorkers: boolean, schema?: string | undefined, startWorkers?: boolean | undefined, stop?: StopOptions | undefined) => Effect.Effect<void, import("#error.ts").PgBossError | PgBossQueueOptionsError, Scope.Scope>;
|
|
8
9
|
//# sourceMappingURL=register.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAqE,MAAM,gBAAgB,CAAC;AACzH,OAAO,EAAE,uBAAuB,EAAiB,MAAM,WAAW,CAAC;AA6BnE,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,eAAe,GAAG,MAAM,CAEtE;AAwED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,SAAS,eAAe,EAAE,GAAG,SAAS,MAAM,EAAE,CAM9F;AAED,eAAO,MAAM,YAAY,GAAgC,CAAC,wTAuBxD,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
1
|
+
import { Effect, Scope } from "effect";
|
|
2
2
|
import { registerWorker } from "#adapters/registerWorker.ts";
|
|
3
|
+
import { workerDiagnostics } from "#adapters/workerDiagnostics.ts";
|
|
3
4
|
import { PgBossQueueOptionsError, toPgBossError } from "#error.ts";
|
|
4
5
|
import { ensureQueue } from "#internal/ensureQueue.ts";
|
|
5
6
|
import { runQueueWorker } from "#internal/runQueueWorker.ts";
|
|
@@ -41,17 +42,17 @@ const prepareQueues = Effect.fnUntraced(function* (client, registrations, replac
|
|
|
41
42
|
function workerContext(context) {
|
|
42
43
|
return context;
|
|
43
44
|
}
|
|
44
|
-
const registerQueue = Effect.fnUntraced(function* (client, registration, context, scope, schema,
|
|
45
|
+
const registerQueue = Effect.fnUntraced(function* (client, registration, context, scope, schema, stop) {
|
|
45
46
|
const queue = registration._tag === "QueueWorker" ? registration.queue : registration;
|
|
46
47
|
const name = queue.name;
|
|
47
48
|
if (registration._tag === "QueueDefinition") {
|
|
48
49
|
return;
|
|
49
50
|
}
|
|
50
|
-
yield* registerWorker(client, name, queue.workerOptions, (job, deadline) => runQueueWorker(registration, job, deadline, client, schema), scope, schema, queue.maxDeferrals,
|
|
51
|
+
yield* registerWorker(client, name, queue.workerOptions, (job, deadline) => runQueueWorker(registration, job, deadline, client, schema), scope, schema, queue.maxDeferrals, stop).pipe(Effect.provide(context));
|
|
51
52
|
});
|
|
52
|
-
const registerSchedule = Effect.fnUntraced(function* (client, worker, context, scope, schema,
|
|
53
|
+
const registerSchedule = Effect.fnUntraced(function* (client, worker, context, scope, schema, stop) {
|
|
53
54
|
const { schedule } = worker;
|
|
54
|
-
yield* registerWorker(client, schedule.name, schedule.workerOptions, () => worker.effect, scope, schema, schedule.maxDeferrals,
|
|
55
|
+
yield* registerWorker(client, schedule.name, schedule.workerOptions, () => workerDiagnostics(worker.effect), scope, schema, schedule.maxDeferrals, stop).pipe(Effect.provide(context));
|
|
55
56
|
yield* Effect.tryPromise({
|
|
56
57
|
catch: (error) => toPgBossError("register", error, schedule.name),
|
|
57
58
|
try: () => client.schedule(schedule.name, schedule.cron, null, schedule.scheduleOptions),
|
|
@@ -64,8 +65,8 @@ export function registrationNames(registrations) {
|
|
|
64
65
|
}
|
|
65
66
|
return names;
|
|
66
67
|
}
|
|
67
|
-
export const registerJobs = Effect.fnUntraced(function* (client, registrations, context, replaceWorkers, schema = "pgboss", startWorkers = true,
|
|
68
|
-
const scope = yield* Effect.scope;
|
|
68
|
+
export const registerJobs = Effect.fnUntraced(function* (client, registrations, context, replaceWorkers, schema = "pgboss", startWorkers = true, stop) {
|
|
69
|
+
const scope = yield* Scope.fork(yield* Effect.scope, "parallel");
|
|
69
70
|
yield* Effect.try({ catch: (error) => toPgBossError("register", error), try: () => registrationNames(registrations) });
|
|
70
71
|
yield* prepareQueues(client, registrations, replaceWorkers);
|
|
71
72
|
if (!startWorkers) {
|
|
@@ -74,10 +75,10 @@ export const registerJobs = Effect.fnUntraced(function* (client, registrations,
|
|
|
74
75
|
const provided = workerContext(context);
|
|
75
76
|
for (const registration of registrations) {
|
|
76
77
|
if (isQueueWorker(registration) || isQueueDefinition(registration)) {
|
|
77
|
-
yield* registerQueue(client, registration, provided, scope, schema,
|
|
78
|
+
yield* registerQueue(client, registration, provided, scope, schema, stop);
|
|
78
79
|
}
|
|
79
80
|
else if (isScheduledWorker(registration)) {
|
|
80
|
-
yield* registerSchedule(client, registration, provided, scope, schema,
|
|
81
|
+
yield* registerSchedule(client, registration, provided, scope, schema, stop);
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Context, Effect, Scope } from "effect";
|
|
2
|
+
import type { StopOptions } from "pg-boss";
|
|
2
3
|
import type { PgBossClient } from "#client.ts";
|
|
3
4
|
import type { JobRegistration } from "#definition.ts";
|
|
4
|
-
export declare const registerReleasedJobs: <R>(client: PgBossClient, jobs: readonly JobRegistration[], context: Context.Context<R>, replaceWorkers: boolean, schema: string | undefined,
|
|
5
|
+
export declare const registerReleasedJobs: <R>(client: PgBossClient, jobs: readonly JobRegistration[], context: Context.Context<R>, replaceWorkers: boolean, schema: string | undefined, stop: StopOptions | undefined, retired?: readonly string[] | undefined) => Effect.Effect<void, import("#error.ts").PgBossError | import("#error.ts").PgBossQueueOptionsError, Scope.Scope>;
|
|
5
6
|
//# sourceMappingURL=registerReleasedJobs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerReleasedJobs.d.ts","sourceRoot":"","sources":["../../../src/server/internal/registerReleasedJobs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"registerReleasedJobs.d.ts","sourceRoot":"","sources":["../../../src/server/internal/registerReleasedJobs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,eAAO,MAAM,oBAAoB,GAAgC,CAAC,sUAyChE,CAAC"}
|
|
@@ -3,15 +3,15 @@ import { WorkerRelease } from "@shivaedev/sql/WorkerRelease.ts";
|
|
|
3
3
|
import { retireJobs } from "#adapters/retireJobs.ts";
|
|
4
4
|
import { toPgBossError } from "#error.ts";
|
|
5
5
|
import { registerJobs, registrationName } from "./register.js";
|
|
6
|
-
export const registerReleasedJobs = Effect.fnUntraced(function* (client, jobs, context, replaceWorkers, schema,
|
|
6
|
+
export const registerReleasedJobs = Effect.fnUntraced(function* (client, jobs, context, replaceWorkers, schema, stop, retired = []) {
|
|
7
7
|
const signal = yield* Effect.serviceOption(WorkerRelease);
|
|
8
8
|
const workers = jobs.filter((job) => job._tag !== "QueueDefinition");
|
|
9
9
|
const scope = yield* Effect.scope;
|
|
10
|
-
const register = retireJobs(client, jobs, retired).pipe(Effect.andThen(registerJobs(client, jobs, context, replaceWorkers, schema, true,
|
|
10
|
+
const register = retireJobs(client, jobs, retired).pipe(Effect.andThen(registerJobs(client, jobs, context, replaceWorkers, schema, true, stop)), Effect.provideService(Scope.Scope, scope));
|
|
11
11
|
if (Option.isNone(signal) || (workers.length === 0 && retired.length === 0)) {
|
|
12
12
|
return yield* register;
|
|
13
13
|
}
|
|
14
|
-
yield* registerJobs(client, jobs, context, replaceWorkers, schema, false,
|
|
14
|
+
yield* registerJobs(client, jobs, context, replaceWorkers, schema, false, stop);
|
|
15
15
|
let working = replaceWorkers;
|
|
16
16
|
let paused = false;
|
|
17
17
|
yield* signal.value.register((active) => Effect.gen(function* () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registerReleasedJobs.js","sourceRoot":"","sources":["../../../src/server/internal/registerReleasedJobs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"registerReleasedJobs.js","sourceRoot":"","sources":["../../../src/server/internal/registerReleasedJobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { Effect } from "effect";
|
|
2
2
|
import type { PgBossClient } from "#client.ts";
|
|
3
|
-
export declare function retryWake(client: PgBossClient, name: string, id: string, registration: Promise<string>): Effect.Effect<void>;
|
|
3
|
+
export declare function retryWake(client: PgBossClient, schema: string, name: string, id: string, registration: Promise<string>): Effect.Effect<void>;
|
|
4
4
|
//# sourceMappingURL=retryWake.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retryWake.d.ts","sourceRoot":"","sources":["../../../src/server/internal/retryWake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"retryWake.d.ts","sourceRoot":"","sources":["../../../src/server/internal/retryWake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CA4B5I"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Clock, Effect } from "effect";
|
|
2
2
|
import { redactDiagnosticCause } from "@shivaedev/errors/redactCause.ts";
|
|
3
|
+
import { batchClockOffset } from "#adapters/batchClockOffset.ts";
|
|
3
4
|
import { toPgBossError } from "#error.ts";
|
|
4
|
-
export function retryWake(client, name, id, registration) {
|
|
5
|
+
export function retryWake(client, schema, name, id, registration) {
|
|
5
6
|
return Effect.gen(function* () {
|
|
6
7
|
const findJobs = client.findJobs?.bind(client);
|
|
7
8
|
if (findJobs === undefined || client.notifyWorker === undefined) {
|
|
@@ -13,8 +14,9 @@ export function retryWake(client, name, id, registration) {
|
|
|
13
14
|
return;
|
|
14
15
|
}
|
|
15
16
|
const workId = yield* Effect.tryPromise({ catch: (error) => toPgBossError("register", error, name), try: () => registration });
|
|
17
|
+
const offset = yield* batchClockOffset(client, schema, name);
|
|
16
18
|
// Host timers can fire early; PostgreSQL retains precision that Date drops.
|
|
17
|
-
const deadline = job.startAfter.getTime() + 1;
|
|
19
|
+
const deadline = job.startAfter.getTime() + offset + 1;
|
|
18
20
|
let remaining = deadline - (yield* Clock.currentTimeMillis);
|
|
19
21
|
while (remaining > 0) {
|
|
20
22
|
yield* Effect.sleep(remaining);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retryWake.js","sourceRoot":"","sources":["../../../src/server/internal/retryWake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"retryWake.js","sourceRoot":"","sources":["../../../src/server/internal/retryWake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,UAAU,SAAS,CAAC,MAAoB,EAAE,MAAc,EAAE,IAAY,EAAE,EAAU,EAAE,YAA6B;IACtH,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,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACjE,OAAO;QACR,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;QACrI,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,EAAE,KAAK,KAAK,OAAO,EAAE,CAAC;YAC5B,OAAO;QACR,CAAC;QACD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;QAC/H,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAC7D,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC;QACvD,IAAI,SAAS,GAAG,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC5D,OAAO,SAAS,GAAG,CAAC,EAAE,CAAC;YACtB,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAC/B,SAAS,GAAG,QAAQ,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,SAAS,GAAG,MAAM;aACtB,UAAU,EAAE,EAAE;aACd,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC;aAC5C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;IACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACtF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAQ,KAAK,EAAE,KAAK,MAAM,EAAE,QAAQ,EAAE,KAAK,MAAM,EAAS,MAAM,QAAQ,CAAC;AACjG,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"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"}
|
package/dist/server/service.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Context, Effect, Exit, Layer, Redacted, Scope } from "effect";
|
|
2
2
|
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
3
3
|
import { genericMethod } from "@shivaedev/service/genericMethod.ts";
|
|
4
|
+
import { clientErrorLogger } from "#adapters/clientErrorLogger.ts";
|
|
4
5
|
import { clientErrorReporter } from "#adapters/clientErrorReporter.ts";
|
|
5
6
|
import { logClientError, subscribeClientErrors } from "#internal/clientErrors.ts";
|
|
6
7
|
import { acquireClient, releaseClient } from "#internal/lifecycle.ts";
|
|
@@ -18,7 +19,7 @@ export function pgBossLayer(options) {
|
|
|
18
19
|
...(connectionString === undefined ? {} : { connectionString: Redacted.value(connectionString) }),
|
|
19
20
|
};
|
|
20
21
|
return Layer.effect(PgBoss, Effect.gen(function* () {
|
|
21
|
-
const report = yield*
|
|
22
|
+
const report = yield* clientErrorLogger();
|
|
22
23
|
const acquired = yield* Effect.acquireRelease(acquireClient({
|
|
23
24
|
clientCacheKey,
|
|
24
25
|
clientFactory,
|
|
@@ -41,7 +42,7 @@ export function makePgBoss(identifier, queueNames) {
|
|
|
41
42
|
const report = yield* clientErrorReporter(reportError).pipe(Effect.provide(context));
|
|
42
43
|
const unsubscribe = subscribeClientErrors(acquired.client, report);
|
|
43
44
|
yield* Effect.addFinalizer(() => Scope.close(workerScope, Exit.void).pipe(Effect.ensuring(Effect.sync(unsubscribe))));
|
|
44
|
-
yield* registerReleasedJobs(acquired.client, options.jobs, context, acquired.reused, acquired.schema, acquired.stop
|
|
45
|
+
yield* registerReleasedJobs(acquired.client, options.jobs, context, acquired.reused, acquired.schema, acquired.stop, options.retired).pipe(Effect.provideService(Scope.Scope, workerScope), Effect.provide(dependencies));
|
|
45
46
|
return service;
|
|
46
47
|
}),
|
|
47
48
|
methods: (service) => ({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAe,QAAQ,EAAe,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEjG,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAKvE,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAkCpC,MAAM,UAAU,WAAW,CAAC,OAAsB;IACjD,MAAM,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,CAAC;IACvF,MAAM,kBAAkB,GAAG;QAC1B,GAAG,QAAQ;QACX,iBAAiB,EAAE,QAAQ,CAAC,iBAAiB,IAAI,MAAM;QACvD,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,IAAI,GAAG;QACtD,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,QAAQ,CAAC,KAAK,CAAC,gBAAgB,CAAC,EAAE,CAAC;KACjG,CAAC;IACF,OAAO,KAAK,CAAC,MAAM,CAClB,MAAM,EACN,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/jobs",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.2",
|
|
4
4
|
"description": "Effect-native jobs and lifecycle management for pg-boss",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -48,16 +48,16 @@
|
|
|
48
48
|
"README.md"
|
|
49
49
|
],
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@shivaedev/errors": "0.
|
|
52
|
-
"@shivaedev/service": "0.6.
|
|
53
|
-
"@shivaedev/sql": "0.
|
|
51
|
+
"@shivaedev/errors": "0.5.0",
|
|
52
|
+
"@shivaedev/service": "0.6.1",
|
|
53
|
+
"@shivaedev/sql": "0.32.0"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
|
-
"@shivaedev/http": "0.
|
|
57
|
-
"@shivaedev/quality": "0.
|
|
58
|
-
"@shivaedev/test": "0.12.
|
|
59
|
-
"@shivaedev/test-sql": "0.16.
|
|
60
|
-
"@shivaedev/test-story": "0.
|
|
56
|
+
"@shivaedev/http": "0.4.0",
|
|
57
|
+
"@shivaedev/quality": "0.55.0",
|
|
58
|
+
"@shivaedev/test": "0.12.1",
|
|
59
|
+
"@shivaedev/test-sql": "0.16.1",
|
|
60
|
+
"@shivaedev/test-story": "0.33.0",
|
|
61
61
|
"@types/node": "24.19.2",
|
|
62
62
|
"effect": "4.0.6",
|
|
63
63
|
"pg-boss": "12.38.0",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { logClientError } from "#internal/clientErrors.ts";
|
|
3
|
+
|
|
4
|
+
export const clientErrorLogger = Effect.fnUntraced(function* () {
|
|
5
|
+
const run = Effect.runForkWith(yield* Effect.context<never>());
|
|
6
|
+
return (error: Error): void => {
|
|
7
|
+
run(Effect.exit(logClientError(error)));
|
|
8
|
+
};
|
|
9
|
+
});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Effect } from "effect";
|
|
1
|
+
import { Effect, FiberSet } from "effect";
|
|
2
2
|
|
|
3
3
|
export const clientErrorReporter = Effect.fnUntraced(function* <R>(report: (error: Error) => Effect.Effect<unknown, never, R>) {
|
|
4
|
-
const run =
|
|
4
|
+
const run = yield* FiberSet.makeRuntime<R>();
|
|
5
5
|
return (error: Error): void => {
|
|
6
|
-
|
|
6
|
+
run(Effect.exit(Effect.suspend(() => report(error))));
|
|
7
7
|
};
|
|
8
8
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect, Fiber, Scope } from "effect";
|
|
2
|
-
import type { Job, WorkOptions } from "pg-boss";
|
|
2
|
+
import type { Job, StopOptions, WorkOptions } from "pg-boss";
|
|
3
3
|
import type { PgBossClient } from "#client.ts";
|
|
4
4
|
import { toPgBossError } from "#error.ts";
|
|
5
5
|
import { batchHandler } from "#internal/batchHandler.ts";
|
|
@@ -15,19 +15,20 @@ export const registerWorker = Effect.fnUntraced(function* <R>(
|
|
|
15
15
|
scope: Scope.Scope,
|
|
16
16
|
schema: string,
|
|
17
17
|
maxDeferrals: number,
|
|
18
|
-
|
|
18
|
+
stop?: StopOptions,
|
|
19
19
|
) {
|
|
20
20
|
const execute = Effect.runPromiseWith(yield* Effect.context<R>());
|
|
21
|
-
const
|
|
21
|
+
const workerScope = yield* Scope.fork(scope);
|
|
22
|
+
const fibers = yield* Scope.fork(workerScope);
|
|
22
23
|
function runJob(job: Job<unknown>, deadline: number) {
|
|
23
24
|
return traceJob(deferrableAttempt(run(job, deadline), client, schema, job, maxDeferrals), job, name);
|
|
24
25
|
}
|
|
25
|
-
function
|
|
26
|
-
return retryWake(client, name, attempt.id, registration).pipe(Effect.forkIn(fibers), Effect.asVoid);
|
|
26
|
+
function afterRetry(attempt: Job<unknown>) {
|
|
27
|
+
return retryWake(client, schema, name, attempt.id, registration).pipe(Effect.forkIn(fibers), Effect.asVoid);
|
|
27
28
|
}
|
|
28
29
|
const handle = yield* Effect.try({
|
|
29
30
|
catch: (error) => toPgBossError("register", error, name),
|
|
30
|
-
try: () => batchHandler(client, name, schema, runJob,
|
|
31
|
+
try: () => batchHandler(client, name, schema, runJob, afterRetry),
|
|
31
32
|
});
|
|
32
33
|
const registration: Promise<string> = yield* Effect.try({
|
|
33
34
|
catch: (error) => toPgBossError("register", error, name),
|
|
@@ -37,12 +38,24 @@ export const registerWorker = Effect.fnUntraced(function* <R>(
|
|
|
37
38
|
),
|
|
38
39
|
});
|
|
39
40
|
const id = yield* Effect.tryPromise({ catch: (error) => toPgBossError("register", error, name), try: () => registration });
|
|
41
|
+
const graceful = stop?.graceful !== false;
|
|
42
|
+
const timeout = stop?.timeout ?? 30_000;
|
|
43
|
+
const drain = Effect.tryPromise({
|
|
44
|
+
catch: (error) => toPgBossError("stop", error, name),
|
|
45
|
+
try: () => client.offWork(name, { id, wait: graceful }),
|
|
46
|
+
});
|
|
40
47
|
yield* Scope.addFinalizer(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
workerScope,
|
|
49
|
+
(graceful
|
|
50
|
+
? drain.pipe(
|
|
51
|
+
Effect.timeoutOrElse({
|
|
52
|
+
duration: timeout,
|
|
53
|
+
orElse: () => Effect.logWarning(`pg-boss worker drain timed out for queue ${name} after ${timeout}ms; interrupting in-flight work`),
|
|
54
|
+
}),
|
|
55
|
+
Effect.interruptible,
|
|
56
|
+
)
|
|
57
|
+
: drain
|
|
58
|
+
).pipe(Effect.catch(Effect.logError)),
|
|
46
59
|
);
|
|
47
60
|
return id;
|
|
48
61
|
});
|
|
@@ -52,7 +52,7 @@ export function batchHandler<R>(
|
|
|
52
52
|
name: string,
|
|
53
53
|
schema: string,
|
|
54
54
|
run: (job: Job<unknown>, deadline: number) => Effect.Effect<unknown, unknown, R>,
|
|
55
|
-
|
|
55
|
+
afterRetry: (job: Job<unknown>) => Effect.Effect<void, unknown> = () => Effect.void,
|
|
56
56
|
) {
|
|
57
57
|
const complete = client.complete?.bind(client);
|
|
58
58
|
const fail = client.fail?.bind(client);
|
|
@@ -73,8 +73,8 @@ export function batchHandler<R>(
|
|
|
73
73
|
return "interrupted";
|
|
74
74
|
}
|
|
75
75
|
yield* settleAttempt(complete, fail, name, job, exit);
|
|
76
|
-
if (Exit.isFailure(exit)) {
|
|
77
|
-
yield*
|
|
76
|
+
if (Exit.isFailure(exit) || exit.value === deferredAttempt) {
|
|
77
|
+
yield* afterRetry(job);
|
|
78
78
|
}
|
|
79
79
|
return "settled";
|
|
80
80
|
});
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import { Effect, Option } from "effect";
|
|
1
|
+
import { Effect, Option, Redacted, Schema } from "effect";
|
|
2
2
|
import { redact } from "@shivaedev/errors/redact.ts";
|
|
3
3
|
import type { PgBossClient } from "#client.ts";
|
|
4
|
-
import { toPgBossError } from "#error.ts";
|
|
4
|
+
import { PgBossPayloadError, toPgBossError } from "#error.ts";
|
|
5
|
+
import { deferralOf } from "#internal/deferral.ts";
|
|
5
6
|
import { decodeStoredData } from "#internal/storedRows.ts";
|
|
7
|
+
import { JobFailure } from "#JobFailure.ts";
|
|
6
8
|
import type { PgBossService } from "#service.ts";
|
|
7
9
|
|
|
10
|
+
const StoredFailure = Schema.Union([JobFailure, Schema.Struct({ value: JobFailure })]);
|
|
11
|
+
|
|
12
|
+
function decodeFailure(queue: string, output: unknown) {
|
|
13
|
+
return Schema.decodeUnknownEffect(StoredFailure)(output).pipe(
|
|
14
|
+
Effect.map((failure) => ("value" in failure ? failure.value : failure)),
|
|
15
|
+
Effect.mapError((error) => new PgBossPayloadError({ direction: "decode", original: Redacted.make(error), queue })),
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
8
19
|
export function getJobFor(client: PgBossClient): PgBossService["getJob"] {
|
|
9
20
|
return (queue, id) =>
|
|
10
21
|
Effect.tryPromise({
|
|
@@ -16,10 +27,16 @@ export function getJobFor(client: PgBossClient): PgBossService["getJob"] {
|
|
|
16
27
|
return (await client.findJobs(queue.name, { id }))[0];
|
|
17
28
|
},
|
|
18
29
|
}).pipe(
|
|
19
|
-
Effect.flatMap(
|
|
20
|
-
job
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
Effect.flatMap(
|
|
31
|
+
Effect.fnUntraced(function* (job) {
|
|
32
|
+
if (job === undefined) {
|
|
33
|
+
return Option.none();
|
|
34
|
+
}
|
|
35
|
+
const data = yield* decodeStoredData(queue, job.data);
|
|
36
|
+
const output = job.output === null || deferralOf(job) !== undefined ? job.output : yield* decodeFailure(queue.name, job.output);
|
|
37
|
+
const sourceOutput = job.sourceOutput === null ? null : yield* decodeFailure(queue.name, job.sourceOutput);
|
|
38
|
+
return Option.some({ ...job, data: redact(data), output, sourceOutput });
|
|
39
|
+
}),
|
|
23
40
|
),
|
|
24
41
|
);
|
|
25
42
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { type Context, Effect,
|
|
1
|
+
import { type Context, Effect, Scope } from "effect";
|
|
2
|
+
import type { StopOptions } from "pg-boss";
|
|
2
3
|
import { registerWorker } from "#adapters/registerWorker.ts";
|
|
4
|
+
import { workerDiagnostics } from "#adapters/workerDiagnostics.ts";
|
|
3
5
|
import type { PgBossClient } from "#client.ts";
|
|
4
6
|
import type { JobRegistration, QueueDefinition, QueueWorker, ScheduleDefinition, ScheduledWorker } from "#definition.ts";
|
|
5
7
|
import { PgBossQueueOptionsError, toPgBossError } from "#error.ts";
|
|
@@ -61,7 +63,7 @@ const registerQueue = Effect.fnUntraced(function* (
|
|
|
61
63
|
context: Context.Context<unknown>,
|
|
62
64
|
scope: Scope.Scope,
|
|
63
65
|
schema: string,
|
|
64
|
-
|
|
66
|
+
stop: StopOptions | undefined,
|
|
65
67
|
) {
|
|
66
68
|
const queue = registration._tag === "QueueWorker" ? registration.queue : registration;
|
|
67
69
|
const name = queue.name;
|
|
@@ -76,7 +78,7 @@ const registerQueue = Effect.fnUntraced(function* (
|
|
|
76
78
|
scope,
|
|
77
79
|
schema,
|
|
78
80
|
queue.maxDeferrals,
|
|
79
|
-
|
|
81
|
+
stop,
|
|
80
82
|
).pipe(Effect.provide(context));
|
|
81
83
|
});
|
|
82
84
|
|
|
@@ -86,12 +88,19 @@ const registerSchedule = Effect.fnUntraced(function* (
|
|
|
86
88
|
context: Context.Context<unknown>,
|
|
87
89
|
scope: Scope.Scope,
|
|
88
90
|
schema: string,
|
|
89
|
-
|
|
91
|
+
stop: StopOptions | undefined,
|
|
90
92
|
) {
|
|
91
93
|
const { schedule } = worker;
|
|
92
|
-
yield* registerWorker(
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
yield* registerWorker(
|
|
95
|
+
client,
|
|
96
|
+
schedule.name,
|
|
97
|
+
schedule.workerOptions,
|
|
98
|
+
() => workerDiagnostics(worker.effect),
|
|
99
|
+
scope,
|
|
100
|
+
schema,
|
|
101
|
+
schedule.maxDeferrals,
|
|
102
|
+
stop,
|
|
103
|
+
).pipe(Effect.provide(context));
|
|
95
104
|
yield* Effect.tryPromise({
|
|
96
105
|
catch: (error) => toPgBossError("register", error, schedule.name),
|
|
97
106
|
try: () => client.schedule(schedule.name, schedule.cron, null, schedule.scheduleOptions),
|
|
@@ -113,9 +122,9 @@ export const registerJobs = Effect.fnUntraced(function* <R>(
|
|
|
113
122
|
replaceWorkers: boolean,
|
|
114
123
|
schema = "pgboss",
|
|
115
124
|
startWorkers = true,
|
|
116
|
-
|
|
125
|
+
stop?: StopOptions,
|
|
117
126
|
) {
|
|
118
|
-
const scope = yield* Effect.scope;
|
|
127
|
+
const scope = yield* Scope.fork(yield* Effect.scope, "parallel");
|
|
119
128
|
yield* Effect.try({ catch: (error) => toPgBossError("register", error), try: () => registrationNames(registrations) });
|
|
120
129
|
yield* prepareQueues(client, registrations, replaceWorkers);
|
|
121
130
|
if (!startWorkers) {
|
|
@@ -124,9 +133,9 @@ export const registerJobs = Effect.fnUntraced(function* <R>(
|
|
|
124
133
|
const provided = workerContext(context);
|
|
125
134
|
for (const registration of registrations) {
|
|
126
135
|
if (isQueueWorker(registration) || isQueueDefinition(registration)) {
|
|
127
|
-
yield* registerQueue(client, registration, provided, scope, schema,
|
|
136
|
+
yield* registerQueue(client, registration, provided, scope, schema, stop);
|
|
128
137
|
} else if (isScheduledWorker(registration)) {
|
|
129
|
-
yield* registerSchedule(client, registration, provided, scope, schema,
|
|
138
|
+
yield* registerSchedule(client, registration, provided, scope, schema, stop);
|
|
130
139
|
}
|
|
131
140
|
}
|
|
132
141
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Context, Effect, Option, Scope } from "effect";
|
|
2
|
+
import type { StopOptions } from "pg-boss";
|
|
2
3
|
import { WorkerRelease } from "@shivaedev/sql/WorkerRelease.ts";
|
|
3
4
|
import { retireJobs } from "#adapters/retireJobs.ts";
|
|
4
5
|
import type { PgBossClient } from "#client.ts";
|
|
@@ -12,20 +13,20 @@ export const registerReleasedJobs = Effect.fnUntraced(function* <R>(
|
|
|
12
13
|
context: Context.Context<R>,
|
|
13
14
|
replaceWorkers: boolean,
|
|
14
15
|
schema: string | undefined,
|
|
15
|
-
|
|
16
|
+
stop: StopOptions | undefined,
|
|
16
17
|
retired: readonly string[] = [],
|
|
17
18
|
) {
|
|
18
19
|
const signal = yield* Effect.serviceOption(WorkerRelease);
|
|
19
20
|
const workers = jobs.filter((job) => job._tag !== "QueueDefinition");
|
|
20
21
|
const scope = yield* Effect.scope;
|
|
21
22
|
const register = retireJobs(client, jobs, retired).pipe(
|
|
22
|
-
Effect.andThen(registerJobs(client, jobs, context, replaceWorkers, schema, true,
|
|
23
|
+
Effect.andThen(registerJobs(client, jobs, context, replaceWorkers, schema, true, stop)),
|
|
23
24
|
Effect.provideService(Scope.Scope, scope),
|
|
24
25
|
);
|
|
25
26
|
if (Option.isNone(signal) || (workers.length === 0 && retired.length === 0)) {
|
|
26
27
|
return yield* register;
|
|
27
28
|
}
|
|
28
|
-
yield* registerJobs(client, jobs, context, replaceWorkers, schema, false,
|
|
29
|
+
yield* registerJobs(client, jobs, context, replaceWorkers, schema, false, stop);
|
|
29
30
|
let working = replaceWorkers;
|
|
30
31
|
let paused = false;
|
|
31
32
|
yield* signal.value.register((active) =>
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Clock, Effect } from "effect";
|
|
2
2
|
import { redactDiagnosticCause } from "@shivaedev/errors/redactCause.ts";
|
|
3
|
+
import { batchClockOffset } from "#adapters/batchClockOffset.ts";
|
|
3
4
|
import type { PgBossClient } from "#client.ts";
|
|
4
5
|
import { toPgBossError } from "#error.ts";
|
|
5
6
|
|
|
6
|
-
export function retryWake(client: PgBossClient, name: string, id: string, registration: Promise<string>): Effect.Effect<void> {
|
|
7
|
+
export function retryWake(client: PgBossClient, schema: string, name: string, id: string, registration: Promise<string>): Effect.Effect<void> {
|
|
7
8
|
return Effect.gen(function* () {
|
|
8
9
|
const findJobs = client.findJobs?.bind(client);
|
|
9
10
|
if (findJobs === undefined || client.notifyWorker === undefined) {
|
|
@@ -15,8 +16,9 @@ export function retryWake(client: PgBossClient, name: string, id: string, regist
|
|
|
15
16
|
return;
|
|
16
17
|
}
|
|
17
18
|
const workId = yield* Effect.tryPromise({ catch: (error) => toPgBossError("register", error, name), try: () => registration });
|
|
19
|
+
const offset = yield* batchClockOffset(client, schema, name);
|
|
18
20
|
// Host timers can fire early; PostgreSQL retains precision that Date drops.
|
|
19
|
-
const deadline = job.startAfter.getTime() + 1;
|
|
21
|
+
const deadline = job.startAfter.getTime() + offset + 1;
|
|
20
22
|
let remaining = deadline - (yield* Clock.currentTimeMillis);
|
|
21
23
|
while (remaining > 0) {
|
|
22
24
|
yield* Effect.sleep(remaining);
|
package/src/server/service.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Context, Effect, Exit, Layer, type Option, Redacted, type Schema, Scope
|
|
|
2
2
|
import type { ConstructorOptions, JobWithMetadata, SendOptions, StopOptions } from "pg-boss";
|
|
3
3
|
import { defineService } from "@shivaedev/service/defineService.ts";
|
|
4
4
|
import { genericMethod } from "@shivaedev/service/genericMethod.ts";
|
|
5
|
+
import { clientErrorLogger } from "#adapters/clientErrorLogger.ts";
|
|
5
6
|
import { clientErrorReporter } from "#adapters/clientErrorReporter.ts";
|
|
6
7
|
import type { PgBossClientFactory } from "#client.ts";
|
|
7
8
|
import type { JobPayloadSchema, JobRegistration, QueueDefinition, RegistrationRequirements } from "#definition.ts";
|
|
@@ -58,7 +59,7 @@ export function pgBossLayer(options: PgBossOptions): Layer.Layer<PgBoss, PgBossE
|
|
|
58
59
|
return Layer.effect(
|
|
59
60
|
PgBoss,
|
|
60
61
|
Effect.gen(function* () {
|
|
61
|
-
const report = yield*
|
|
62
|
+
const report = yield* clientErrorLogger();
|
|
62
63
|
const acquired = yield* Effect.acquireRelease(
|
|
63
64
|
acquireClient(
|
|
64
65
|
{
|
|
@@ -105,15 +106,10 @@ export function makePgBoss<const TIdentifier extends string>(identifier: TIdenti
|
|
|
105
106
|
const report = yield* clientErrorReporter(reportError).pipe(Effect.provide(context));
|
|
106
107
|
const unsubscribe = subscribeClientErrors(acquired.client, report);
|
|
107
108
|
yield* Effect.addFinalizer(() => Scope.close(workerScope, Exit.void).pipe(Effect.ensuring(Effect.sync(unsubscribe))));
|
|
108
|
-
yield* registerReleasedJobs(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
acquired.reused,
|
|
113
|
-
acquired.schema,
|
|
114
|
-
acquired.stop?.graceful !== false,
|
|
115
|
-
options.retired,
|
|
116
|
-
).pipe(Effect.provideService(Scope.Scope, workerScope), Effect.provide(dependencies));
|
|
109
|
+
yield* registerReleasedJobs(acquired.client, options.jobs, context, acquired.reused, acquired.schema, acquired.stop, options.retired).pipe(
|
|
110
|
+
Effect.provideService(Scope.Scope, workerScope),
|
|
111
|
+
Effect.provide(dependencies),
|
|
112
|
+
);
|
|
117
113
|
return service;
|
|
118
114
|
}),
|
|
119
115
|
methods: (service) => ({
|