@shivaedev/jobs 0.31.0 → 0.32.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 +24 -0
- package/README.md +57 -26
- package/dist/server/adapters/inspection.d.ts +5 -0
- package/dist/server/adapters/inspection.d.ts.map +1 -0
- package/dist/server/adapters/inspection.js +25 -0
- package/dist/server/adapters/inspection.js.map +1 -0
- package/dist/server/adapters/inspectionChanges.d.ts +7 -0
- package/dist/server/adapters/inspectionChanges.d.ts.map +1 -0
- package/dist/server/adapters/inspectionChanges.js +23 -0
- package/dist/server/adapters/inspectionChanges.js.map +1 -0
- package/dist/server/adapters/inspectionDeferrals.d.ts +10 -0
- package/dist/server/adapters/inspectionDeferrals.d.ts.map +1 -0
- package/dist/server/adapters/inspectionDeferrals.js +13 -0
- package/dist/server/adapters/inspectionDeferrals.js.map +1 -0
- package/dist/server/adapters/inspectionJobs.d.ts +50 -0
- package/dist/server/adapters/inspectionJobs.d.ts.map +1 -0
- package/dist/server/adapters/inspectionJobs.js +21 -0
- package/dist/server/adapters/inspectionJobs.js.map +1 -0
- package/dist/server/adapters/inspectionOperation.d.ts +3 -0
- package/dist/server/adapters/inspectionOperation.d.ts.map +1 -0
- package/dist/server/adapters/inspectionOperation.js +6 -0
- package/dist/server/adapters/inspectionOperation.js.map +1 -0
- package/dist/server/adapters/inspectionPlan.d.ts +3 -0
- package/dist/server/adapters/inspectionPlan.d.ts.map +1 -0
- package/dist/server/adapters/inspectionPlan.js +20 -0
- package/dist/server/adapters/inspectionPlan.js.map +1 -0
- package/dist/server/adapters/inspectionReads.d.ts +59 -0
- package/dist/server/adapters/inspectionReads.d.ts.map +1 -0
- package/dist/server/adapters/inspectionReads.js +44 -0
- package/dist/server/adapters/inspectionReads.js.map +1 -0
- package/dist/server/adapters/inspectionSnapshot.d.ts +6 -0
- package/dist/server/adapters/inspectionSnapshot.d.ts.map +1 -0
- package/dist/server/{internal/testingSnapshot.js → adapters/inspectionSnapshot.js} +9 -7
- package/dist/server/adapters/inspectionSnapshot.js.map +1 -0
- package/dist/server/adapters/jobEngine.d.ts.map +1 -1
- package/dist/server/adapters/jobEngine.js +0 -4
- package/dist/server/adapters/jobEngine.js.map +1 -1
- package/dist/server/adapters/payloadIdentity.d.ts +3 -0
- package/dist/server/adapters/payloadIdentity.d.ts.map +1 -0
- package/dist/server/adapters/payloadIdentity.js +14 -0
- package/dist/server/adapters/payloadIdentity.js.map +1 -0
- package/dist/server/{internal/testingSignal.d.ts → adapters/queueSignal.d.ts} +2 -2
- package/dist/server/adapters/queueSignal.d.ts.map +1 -0
- package/dist/server/{internal/testingSignal.js → adapters/queueSignal.js} +2 -2
- package/dist/server/adapters/queueSignal.js.map +1 -0
- package/dist/server/adapters/testingClient.d.ts +1 -2
- package/dist/server/adapters/testingClient.d.ts.map +1 -1
- package/dist/server/adapters/testingClient.js +23 -45
- package/dist/server/adapters/testingClient.js.map +1 -1
- package/dist/server/adapters/testingController.d.ts +57 -12
- package/dist/server/adapters/testingController.d.ts.map +1 -1
- package/dist/server/adapters/testingController.js +28 -18
- package/dist/server/adapters/testingController.js.map +1 -1
- package/dist/server/adapters/testingDueNow.js +1 -1
- package/dist/server/adapters/testingDueNow.js.map +1 -1
- package/dist/server/adapters/testingEngine.d.ts.map +1 -1
- package/dist/server/adapters/testingEngine.js +0 -11
- package/dist/server/adapters/testingEngine.js.map +1 -1
- package/dist/server/adapters/testingInspectionClient.d.ts +5 -0
- package/dist/server/adapters/testingInspectionClient.d.ts.map +1 -0
- package/dist/server/adapters/testingInspectionClient.js +52 -0
- package/dist/server/adapters/testingInspectionClient.js.map +1 -0
- package/dist/server/client.d.ts +3 -0
- package/dist/server/client.d.ts.map +1 -1
- package/dist/server/clientOptions.d.ts +0 -1
- package/dist/server/clientOptions.d.ts.map +1 -1
- package/dist/server/definition.d.ts +12 -11
- package/dist/server/definition.d.ts.map +1 -1
- package/dist/server/definition.js +2 -1
- package/dist/server/definition.js.map +1 -1
- package/dist/server/engineClient.d.ts +0 -5
- package/dist/server/engineClient.d.ts.map +1 -1
- package/dist/server/enqueueOptions.d.ts +6 -0
- package/dist/server/enqueueOptions.d.ts.map +1 -1
- package/dist/server/error.d.ts +1 -1
- package/dist/server/error.d.ts.map +1 -1
- package/dist/server/error.js.map +1 -1
- package/dist/server/inspection.d.ts +102 -0
- package/dist/server/inspection.d.ts.map +1 -0
- package/dist/server/inspection.js +30 -0
- package/dist/server/inspection.js.map +1 -0
- package/dist/server/internal/adapters/testingFetches.d.ts +2 -2
- package/dist/server/internal/adapters/testingFetches.d.ts.map +1 -1
- package/dist/server/internal/adapters/testingFetches.js.map +1 -1
- package/dist/server/internal/deferral.d.ts +0 -2
- package/dist/server/internal/deferral.d.ts.map +1 -1
- package/dist/server/internal/deferral.js +0 -1
- package/dist/server/internal/deferral.js.map +1 -1
- package/dist/server/internal/engine.d.ts +0 -5
- package/dist/server/internal/engine.d.ts.map +1 -1
- package/dist/server/internal/engine.js.map +1 -1
- package/dist/server/internal/enqueueFor.d.ts.map +1 -1
- package/dist/server/internal/enqueueFor.js +11 -1
- package/dist/server/internal/enqueueFor.js.map +1 -1
- package/dist/server/internal/jobStorePlans.d.ts.map +1 -1
- package/dist/server/internal/jobStorePlans.js +2 -1
- package/dist/server/internal/jobStorePlans.js.map +1 -1
- package/dist/server/internal/makeService.d.ts.map +1 -1
- package/dist/server/internal/makeService.js +7 -6
- package/dist/server/internal/makeService.js.map +1 -1
- package/dist/server/internal/register.d.ts.map +1 -1
- package/dist/server/internal/register.js +0 -4
- package/dist/server/internal/register.js.map +1 -1
- package/dist/server/internal/testingIdle.d.ts +3 -2
- package/dist/server/internal/testingIdle.d.ts.map +1 -1
- package/dist/server/internal/testingIdle.js +5 -25
- package/dist/server/internal/testingIdle.js.map +1 -1
- package/dist/server/internal/testingOperation.d.ts +5 -0
- package/dist/server/internal/testingOperation.d.ts.map +1 -0
- package/dist/server/internal/testingOperation.js +12 -0
- package/dist/server/internal/testingOperation.js.map +1 -0
- package/dist/server/internal/testingSchedules.d.ts +8 -5
- package/dist/server/internal/testingSchedules.d.ts.map +1 -1
- package/dist/server/internal/testingSchedules.js +14 -9
- package/dist/server/internal/testingSchedules.js.map +1 -1
- package/dist/server/internal/testingWaits.d.ts +7 -4
- package/dist/server/internal/testingWaits.d.ts.map +1 -1
- package/dist/server/internal/testingWaits.js +5 -6
- package/dist/server/internal/testingWaits.js.map +1 -1
- package/dist/server/schema.d.ts.map +1 -1
- package/dist/server/schema.js +5 -0
- package/dist/server/schema.js.map +1 -1
- package/dist/server/service.d.ts +4 -4
- package/dist/server/service.d.ts.map +1 -1
- package/dist/server/service.js +1 -0
- package/dist/server/service.js.map +1 -1
- package/dist/server/testing.d.ts +60 -25
- package/dist/server/testing.d.ts.map +1 -1
- package/dist/server/testing.js.map +1 -1
- package/package.json +6 -6
- package/src/server/adapters/inspection.ts +31 -0
- package/src/server/adapters/inspectionChanges.ts +31 -0
- package/src/server/{internal/testingDeferrals.ts → adapters/inspectionDeferrals.ts} +10 -12
- package/src/server/adapters/inspectionJobs.ts +28 -0
- package/src/server/adapters/inspectionOperation.ts +6 -0
- package/src/server/adapters/inspectionPlan.ts +21 -0
- package/src/server/adapters/inspectionReads.ts +55 -0
- package/src/server/{internal/testingSnapshot.ts → adapters/inspectionSnapshot.ts} +15 -17
- package/src/server/adapters/jobEngine.ts +0 -4
- package/src/server/adapters/payloadIdentity.ts +15 -0
- package/src/server/{internal/testingSignal.ts → adapters/queueSignal.ts} +1 -1
- package/src/server/adapters/testingClient.ts +9 -30
- package/src/server/adapters/testingController.ts +37 -21
- package/src/server/adapters/testingDueNow.ts +1 -1
- package/src/server/adapters/testingEngine.ts +0 -13
- package/src/server/adapters/testingInspectionClient.ts +70 -0
- package/src/server/client.ts +3 -0
- package/src/server/clientOptions.ts +0 -1
- package/src/server/definition.ts +18 -12
- package/src/server/engineClient.ts +0 -2
- package/src/server/enqueueOptions.ts +5 -0
- package/src/server/error.ts +1 -0
- package/src/server/inspection.ts +50 -0
- package/src/server/internal/adapters/testingFetches.ts +2 -2
- package/src/server/internal/deferral.ts +0 -2
- package/src/server/internal/engine.ts +0 -6
- package/src/server/internal/enqueueFor.ts +14 -1
- package/src/server/internal/jobStorePlans.ts +2 -1
- package/src/server/internal/makeService.ts +7 -6
- package/src/server/internal/register.ts +0 -4
- package/src/server/internal/testingIdle.ts +7 -30
- package/src/server/internal/testingOperation.ts +18 -0
- package/src/server/internal/testingSchedules.ts +28 -16
- package/src/server/internal/testingWaits.ts +10 -11
- package/src/server/schema.ts +5 -0
- package/src/server/service.ts +5 -2
- package/src/server/testing.ts +1 -12
- package/dist/server/adapters/observeTestingSettlements.d.ts +0 -6
- package/dist/server/adapters/observeTestingSettlements.d.ts.map +0 -1
- package/dist/server/adapters/observeTestingSettlements.js +0 -35
- package/dist/server/adapters/observeTestingSettlements.js.map +0 -1
- package/dist/server/internal/testingDeferrals.d.ts +0 -10
- package/dist/server/internal/testingDeferrals.d.ts.map +0 -1
- package/dist/server/internal/testingDeferrals.js +0 -15
- package/dist/server/internal/testingDeferrals.js.map +0 -1
- package/dist/server/internal/testingReadout.d.ts +0 -10
- package/dist/server/internal/testingReadout.d.ts.map +0 -1
- package/dist/server/internal/testingReadout.js +0 -13
- package/dist/server/internal/testingReadout.js.map +0 -1
- package/dist/server/internal/testingRegistrations.d.ts +0 -4
- package/dist/server/internal/testingRegistrations.d.ts.map +0 -1
- package/dist/server/internal/testingRegistrations.js +0 -8
- package/dist/server/internal/testingRegistrations.js.map +0 -1
- package/dist/server/internal/testingSignal.d.ts.map +0 -1
- package/dist/server/internal/testingSignal.js.map +0 -1
- package/dist/server/internal/testingSnapshot.d.ts +0 -6
- package/dist/server/internal/testingSnapshot.d.ts.map +0 -1
- package/dist/server/internal/testingSnapshot.js.map +0 -1
- package/src/server/adapters/observeTestingSettlements.ts +0 -36
- package/src/server/internal/testingReadout.ts +0 -25
- package/src/server/internal/testingRegistrations.ts +0 -10
package/dist/server/testing.d.ts
CHANGED
|
@@ -1,41 +1,76 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import type { JobPayloadSchema, QueueDefinition } from "#server/definition.ts";
|
|
1
|
+
import { type Duration, Effect, type Tracer } from "effect";
|
|
3
2
|
export declare function makePgBossTesting(options?: PgBossTestingOptions): {
|
|
4
|
-
runDeferredNow: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
5
|
-
runDueNow: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
6
|
-
deferred: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<{
|
|
7
|
-
at: DateTime.Utc;
|
|
8
|
-
reason: string;
|
|
9
|
-
}[], import("./error.ts").PgBossTestingError, never>;
|
|
3
|
+
runDeferredNow: (queue: Pick<import("./definition.ts").QueueDefinition, "name">) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
4
|
+
runDueNow: (queue: Pick<import("./definition.ts").QueueDefinition, "name">) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
10
5
|
schedules: () => Effect.Effect<{
|
|
11
6
|
cron: string;
|
|
12
7
|
name: string;
|
|
13
8
|
timezone: string;
|
|
14
9
|
}[], import("./error.ts").PgBossTestingError, never>;
|
|
15
|
-
trigger: (schedule: Pick<import("
|
|
16
|
-
fetchesPass: (queue: Pick<QueueDefinition, "name">, count: number, options?: PgBossTestingWaitOptions) => Effect.Effect<unknown, import("./error.ts").PgBossTestingError | import("./error.ts").PgBossWaitError, never>;
|
|
17
|
-
untilJob: <TName extends string, TPayload extends
|
|
18
|
-
|
|
10
|
+
trigger: (schedule: Pick<import("./definition.ts").ScheduleDefinition, "name" | "scheduleOptions">) => Effect.Effect<string | null, import("./error.ts").PgBossTestingError, never>;
|
|
11
|
+
fetchesPass: (queue: Pick<import("./definition.ts").QueueDefinition, "name">, count: number, options?: PgBossTestingWaitOptions) => Effect.Effect<unknown, import("./error.ts").PgBossTestingError | import("./error.ts").PgBossWaitError, never>;
|
|
12
|
+
untilJob: <TName extends string, TPayload extends import("./definition.ts").JobPayloadSchema | typeof import("effect/Schema").Null>(queue: {
|
|
13
|
+
readonly name: TName;
|
|
14
|
+
readonly schema: TPayload;
|
|
15
|
+
}, id: string, state: import("./job.ts").JobState, options?: PgBossTestingWaitOptions) => Effect.Effect<import("./job.ts").Job<TPayload["Type"]>, import("./error.ts").PgBossPayloadError | import("./error.ts").PgBossTestingError | import("./error.ts").PgBossWaitError, Exclude<TPayload["DecodingServices"], never>>;
|
|
16
|
+
deferred: (queue: Pick<import("./definition.ts").QueueDefinition, "name">) => Effect.Effect<{
|
|
17
|
+
at: import("effect/DateTime").Utc;
|
|
18
|
+
reason: string;
|
|
19
|
+
}[], import("./error.ts").PgBossTestingError, never>;
|
|
20
|
+
checkBatchWindow: (queue: Pick<import("./definition.ts").QueueDefinition, "name" | "workerOptions">, millisecondsPerJob: number) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
19
21
|
checkSchemaVersion: (expected: number) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
20
22
|
clientFactory: import("./client.ts").PgBossClientFactory;
|
|
21
|
-
expireAfter: (queue: Pick<QueueDefinition, "name">, attempts: number) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
22
|
-
expireIn: (queue: Pick<QueueDefinition, "name">, duration: Duration.Input) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
23
|
-
failNextSend: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<void, never, never>;
|
|
24
|
-
jobs: <TName extends string, TPayload extends
|
|
23
|
+
expireAfter: (queue: Pick<import("./definition.ts").QueueDefinition, "name">, attempts: number) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
24
|
+
expireIn: (queue: Pick<import("./definition.ts").QueueDefinition, "name">, duration: Duration.Input) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
25
|
+
failNextSend: (queue: Pick<import("./definition.ts").QueueDefinition, "name">) => Effect.Effect<void, never, never>;
|
|
26
|
+
jobs: <TName extends string, TPayload extends import("./definition.ts").JobPayloadSchema | typeof import("effect/Schema").Null>(queue: {
|
|
27
|
+
readonly name: TName;
|
|
28
|
+
readonly schema: TPayload;
|
|
29
|
+
}, readOptions?: import("./client.ts").JobReadOptions) => Effect.Effect<{
|
|
30
|
+
expireInSeconds: number;
|
|
31
|
+
groupId?: string | null;
|
|
32
|
+
groupTier?: string | null;
|
|
33
|
+
heartbeatSeconds: number | null;
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
retryCount: number;
|
|
37
|
+
signal: AbortSignal;
|
|
38
|
+
blocked: boolean;
|
|
39
|
+
blocking: boolean;
|
|
40
|
+
completedOn: Date | null;
|
|
41
|
+
createdOn: Date;
|
|
42
|
+
deadLetter: string;
|
|
43
|
+
deleteAfterSeconds: number;
|
|
44
|
+
heartbeatOn: Date | null;
|
|
45
|
+
keepUntil: Date;
|
|
46
|
+
output: object | null;
|
|
47
|
+
pendingDependencies: number;
|
|
48
|
+
policy: string;
|
|
49
|
+
priority: number;
|
|
50
|
+
retryBackoff: boolean;
|
|
51
|
+
retryDelay: number;
|
|
52
|
+
retryDelayMax?: number;
|
|
53
|
+
retryLimit: number;
|
|
54
|
+
singletonKey: string | null;
|
|
55
|
+
singletonOn: Date | null;
|
|
56
|
+
sourceCreatedOn: Date | null;
|
|
57
|
+
sourceId: string | null;
|
|
58
|
+
sourceName: string | null;
|
|
59
|
+
sourceOutput: object | null;
|
|
60
|
+
sourceRetryCount: number | null;
|
|
61
|
+
sourceRootId: string | null;
|
|
62
|
+
startAfter: Date;
|
|
63
|
+
startedOn: Date | null;
|
|
64
|
+
state: import("./job.ts").JobState;
|
|
65
|
+
data: TPayload["Type"];
|
|
66
|
+
}[], import("./error.ts").PgBossPayloadError | import("./error.ts").PgBossTestingError, TPayload["DecodingServices"]>;
|
|
67
|
+
refreshQueueStats: (queue?: Pick<import("./definition.ts").QueueDefinition, "name">) => Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
25
68
|
revision: Effect.Effect<number, never, never>;
|
|
26
69
|
schemaVersion: Effect.Effect<number | null, import("./error.ts").PgBossTestingError, never>;
|
|
27
|
-
snapshot: <const TQueues extends readonly SnapshotQueue[]>(queues: TQueues) => Effect.Effect<readonly UnfinishedJob<TQueues[number]>[], import("./error.ts").PgBossPayloadError | import("./error.ts").PgBossTestingError, TQueues[number]["schema"]["DecodingServices"]>;
|
|
70
|
+
snapshot: <const TQueues extends readonly import("./inspection.ts").SnapshotQueue[]>(queues: TQueues) => Effect.Effect<readonly import("./inspection.ts").UnfinishedJob<TQueues[number]>[], import("./error.ts").PgBossPayloadError | import("./error.ts").PgBossTestingError, TQueues[number]["schema"]["DecodingServices"]>;
|
|
28
71
|
waitForChange: (after: number) => Effect.Effect<number>;
|
|
29
72
|
waitForIdle: Effect.Effect<void, import("./error.ts").PgBossTestingError, never>;
|
|
30
73
|
};
|
|
31
|
-
export type SnapshotQueue = Pick<QueueDefinition<string, JobPayloadSchema>, "name" | "schema">;
|
|
32
|
-
export interface UnfinishedJob<TQueue extends SnapshotQueue> {
|
|
33
|
-
readonly data: TQueue["schema"]["Type"];
|
|
34
|
-
readonly id: string;
|
|
35
|
-
readonly queue: TQueue["name"];
|
|
36
|
-
readonly startAfter: DateTime.Utc;
|
|
37
|
-
readonly state: "active" | "created" | "deferred" | "failed" | "retry";
|
|
38
|
-
}
|
|
39
74
|
export interface PgBossTestingWaitOptions {
|
|
40
75
|
readonly within?: Duration.Input;
|
|
41
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG5D,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,oBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEnE;AAED,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;CACjC;AAED,eAAO,MAAM,eAAe;;;EAAwD,CAAC;AAErF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,eAAe,CAAC;CAC9C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,GAAG,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,MAAM,CAAC,IAAI,EAAE,8CASlH;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAe,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAE1E,MAAM,UAAU,iBAAiB,CAAC,OAAO,GAAyB,EAAE;IACnE,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAMD,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAMrF,MAAM,UAAU,iBAAiB,CAAC,MAAkD,EAAE,KAA6B;IAClH,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CACvB,KAAK,CAAC,MAAM,CACX,CAAC,IAAI,EAAE,EAAE,CACR,IAAI,CAAC,IAAI,KAAK,UAAU;WACrB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,SAAS;WACrD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CACzG,CACD,CAAC;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/jobs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.0",
|
|
4
4
|
"description": "Effect-native jobs and lifecycle management for pg-boss",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"effect"
|
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
"README.md"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@shivaedev/errors": "0.
|
|
46
|
+
"@shivaedev/errors": "0.7.0",
|
|
47
47
|
"@shivaedev/service": "0.6.1",
|
|
48
|
-
"@shivaedev/sql": "0.
|
|
48
|
+
"@shivaedev/sql": "0.35.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@shivaedev/http": "0.5.0",
|
|
52
|
-
"@shivaedev/quality": "0.57.
|
|
52
|
+
"@shivaedev/quality": "0.57.1",
|
|
53
53
|
"@shivaedev/test": "0.14.0",
|
|
54
|
-
"@shivaedev/test-sql": "0.
|
|
55
|
-
"@shivaedev/test-story": "0.
|
|
54
|
+
"@shivaedev/test-sql": "0.18.0",
|
|
55
|
+
"@shivaedev/test-story": "0.36.0",
|
|
56
56
|
"@types/node": "24.19.2",
|
|
57
57
|
"effect": "4.0.6",
|
|
58
58
|
"pg-boss": "12.38.0",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { jobEngine } from "#server/adapters/jobEngine.ts";
|
|
3
|
+
import type { PgBossClient } from "#server/client.ts";
|
|
4
|
+
import type { PgBossInspectionService } from "#server/inspection.ts";
|
|
5
|
+
import { countsFor } from "#server/internal/countsFor.ts";
|
|
6
|
+
import { JobEngine } from "#server/internal/engine.ts";
|
|
7
|
+
import { healthFor } from "#server/internal/healthFor.ts";
|
|
8
|
+
import { jobControl } from "#server/internal/jobControl.ts";
|
|
9
|
+
import { jobListings } from "#server/internal/jobListings.ts";
|
|
10
|
+
import { inspectionChanges } from "./inspectionChanges.ts";
|
|
11
|
+
import { inspectionReads } from "./inspectionReads.ts";
|
|
12
|
+
|
|
13
|
+
export function inspection(client: PgBossClient, schema = "pgboss"): Effect.Effect<PgBossInspectionService> {
|
|
14
|
+
const engine = jobEngine(client, schema);
|
|
15
|
+
return Effect.gen(function* () {
|
|
16
|
+
const listings = yield* jobListings;
|
|
17
|
+
const { getJob } = yield* jobControl;
|
|
18
|
+
return {
|
|
19
|
+
...inspectionReads(client, schema),
|
|
20
|
+
...listings,
|
|
21
|
+
changes: (queue?: { readonly name: string }) => inspectionChanges(client, schema, queue?.name),
|
|
22
|
+
counts: (queue: { readonly name: string }) => countsFor(client, schema, queue.name),
|
|
23
|
+
getJob,
|
|
24
|
+
health: (queues: readonly { readonly name: string }[]) =>
|
|
25
|
+
healthFor(
|
|
26
|
+
client,
|
|
27
|
+
queues.map((queue) => queue.name),
|
|
28
|
+
),
|
|
29
|
+
};
|
|
30
|
+
}).pipe(Effect.provideService(JobEngine, engine));
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { inspectionChannel } from "#server/adapters/inspectionPlan.ts";
|
|
3
|
+
import type { PgBossClient } from "#server/client.ts";
|
|
4
|
+
import { toPgBossError } from "#server/error.ts";
|
|
5
|
+
import { queueSignal } from "./queueSignal.ts";
|
|
6
|
+
|
|
7
|
+
export const inspectionChanges = Effect.fnUntraced(function* (client: PgBossClient, schema: string, queue?: string) {
|
|
8
|
+
const signal = queueSignal();
|
|
9
|
+
yield* Effect.acquireRelease(
|
|
10
|
+
Effect.tryPromise({
|
|
11
|
+
catch: (error) => toPgBossError("inspect", error, queue),
|
|
12
|
+
try: () => {
|
|
13
|
+
const db = client.getDb?.();
|
|
14
|
+
if (db?.listen === undefined) {
|
|
15
|
+
throw new TypeError("This pg-boss client does not support listen");
|
|
16
|
+
}
|
|
17
|
+
return db.listen(
|
|
18
|
+
inspectionChannel(schema),
|
|
19
|
+
(name) => {
|
|
20
|
+
if (queue === undefined || name === queue) {
|
|
21
|
+
signal.changed();
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
signal.changed,
|
|
25
|
+
);
|
|
26
|
+
},
|
|
27
|
+
}),
|
|
28
|
+
(listener) => Effect.promise(() => listener.close()),
|
|
29
|
+
);
|
|
30
|
+
return { revision: signal.revision, waitForChange: signal.waitForChange };
|
|
31
|
+
});
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import { DateTime } from "effect";
|
|
1
|
+
import { DateTime, Effect } from "effect";
|
|
2
|
+
import type { PgBossClient } from "#server/client.ts";
|
|
2
3
|
import type { QueueDefinition } from "#server/definition.ts";
|
|
3
|
-
import type { EngineClient } from "#server/engineClient.ts";
|
|
4
4
|
import { deferralOf } from "#server/internal/deferral.ts";
|
|
5
|
-
import {
|
|
5
|
+
import { inspectionJobs } from "./inspectionJobs.ts";
|
|
6
6
|
|
|
7
|
-
export function
|
|
7
|
+
export function inspectionDeferrals(client: PgBossClient) {
|
|
8
|
+
const { storedJobs } = inspectionJobs(client);
|
|
8
9
|
return {
|
|
9
10
|
deferred: (queue: Pick<QueueDefinition, "name">) =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const jobs = await client().findJobs(queue.name);
|
|
14
|
-
return jobs.flatMap((job) => {
|
|
11
|
+
storedJobs(queue).pipe(
|
|
12
|
+
Effect.map((jobs) =>
|
|
13
|
+
jobs.flatMap((job) => {
|
|
15
14
|
const deferral = job.state === "retry" && job.startedOn === null ? deferralOf(job) : undefined;
|
|
16
15
|
return deferral === undefined ? [] : [{ at: DateTime.makeUnsafe(job.startAfter), reason: deferral.reason }];
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
queue.name,
|
|
16
|
+
}),
|
|
17
|
+
),
|
|
20
18
|
),
|
|
21
19
|
};
|
|
22
20
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Effect, type Schema } from "effect";
|
|
2
|
+
import type { JobReadOptions, PgBossClient } from "#server/client.ts";
|
|
3
|
+
import type { JobPayloadSchema } from "#server/definition.ts";
|
|
4
|
+
import { toPgBossError } from "#server/error.ts";
|
|
5
|
+
import { decodeStoredData } from "#server/internal/storedRows.ts";
|
|
6
|
+
|
|
7
|
+
export function inspectionJobs(client: PgBossClient) {
|
|
8
|
+
function storedJobs(queue: { readonly name: string }, options?: JobReadOptions) {
|
|
9
|
+
return Effect.tryPromise({
|
|
10
|
+
catch: (error) => toPgBossError("inspect", error, queue.name),
|
|
11
|
+
try: () => {
|
|
12
|
+
if (client.findJobs === undefined) {
|
|
13
|
+
throw new TypeError("This pg-boss client does not support findJobs");
|
|
14
|
+
}
|
|
15
|
+
return client.findJobs(queue.name, options);
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function jobs<TName extends string, TPayload extends JobPayloadSchema | typeof Schema.Null>(
|
|
20
|
+
queue: { readonly name: TName; readonly schema: TPayload },
|
|
21
|
+
options?: JobReadOptions,
|
|
22
|
+
) {
|
|
23
|
+
return storedJobs(queue, options).pipe(
|
|
24
|
+
Effect.flatMap((rows) => Effect.forEach(rows, (job) => decodeStoredData(queue, job.data).pipe(Effect.map((data) => ({ ...job, data }))))),
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return { jobs, storedJobs };
|
|
28
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { toPgBossError } from "#server/error.ts";
|
|
3
|
+
|
|
4
|
+
export function inspectionOperation<A>(run: () => Promise<A>, queue?: string) {
|
|
5
|
+
return Effect.tryPromise({ catch: (error) => toPgBossError("inspect", error, queue), try: run });
|
|
6
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { quotedSchema } from "#server/internal/storedRows.ts";
|
|
2
|
+
|
|
3
|
+
export function inspectionChannel(schema: string): string {
|
|
4
|
+
return `jobs:${schema}`;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function inspectionPlan(schema: string): string {
|
|
8
|
+
const quoted = quotedSchema(schema);
|
|
9
|
+
const channel = inspectionChannel(schema).replaceAll("'", "''");
|
|
10
|
+
const body = `BEGIN
|
|
11
|
+
CREATE OR REPLACE FUNCTION ${quoted}.effect_job_changed() RETURNS trigger LANGUAGE plpgsql AS $body$
|
|
12
|
+
BEGIN
|
|
13
|
+
PERFORM pg_notify('${channel}', COALESCE(NEW.name, OLD.name));
|
|
14
|
+
RETURN NULL;
|
|
15
|
+
END
|
|
16
|
+
$body$;
|
|
17
|
+
CREATE OR REPLACE TRIGGER effect_job_changed AFTER INSERT OR UPDATE OR DELETE ON ${quoted}.job
|
|
18
|
+
FOR EACH ROW EXECUTE FUNCTION ${quoted}.effect_job_changed();
|
|
19
|
+
END`;
|
|
20
|
+
return `DO '${body.replaceAll("'", "''")}'`;
|
|
21
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { inspectionDeferrals } from "#server/adapters/inspectionDeferrals.ts";
|
|
3
|
+
import { inspectionJobs } from "#server/adapters/inspectionJobs.ts";
|
|
4
|
+
import { inspectionOperation } from "#server/adapters/inspectionOperation.ts";
|
|
5
|
+
import { inspectionSnapshot } from "#server/adapters/inspectionSnapshot.ts";
|
|
6
|
+
import type { PgBossClient } from "#server/client.ts";
|
|
7
|
+
import type { QueueDefinition } from "#server/definition.ts";
|
|
8
|
+
import { quotedSchema } from "#server/internal/storedRows.ts";
|
|
9
|
+
|
|
10
|
+
const Busy = Schema.Struct({ busy: Schema.Boolean });
|
|
11
|
+
export function inspectionReads(client: PgBossClient, schema: string) {
|
|
12
|
+
const quoted = quotedSchema(schema);
|
|
13
|
+
function query(text: string, values?: unknown[]) {
|
|
14
|
+
const db = client.getDb?.();
|
|
15
|
+
if (db === undefined) {
|
|
16
|
+
throw new TypeError("This pg-boss client does not support getDb");
|
|
17
|
+
}
|
|
18
|
+
return db.executeSql(text, values);
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
...inspectionDeferrals(client),
|
|
22
|
+
busy: (queues: readonly Pick<QueueDefinition, "name">[]) =>
|
|
23
|
+
inspectionOperation(async () => {
|
|
24
|
+
const { rows } = await query(
|
|
25
|
+
`/* jobs inspection busy */ SELECT EXISTS (
|
|
26
|
+
SELECT 1 FROM ${quoted}.job WHERE name = ANY($1::text[]) AND (
|
|
27
|
+
(state < 'active' AND NOT blocked AND start_after <= ${quoted}.job_now()) OR state = 'active'
|
|
28
|
+
)
|
|
29
|
+
) AS busy`,
|
|
30
|
+
[queues.map(({ name }) => name)],
|
|
31
|
+
);
|
|
32
|
+
return Schema.decodeUnknownSync(Busy)(rows[0]).busy;
|
|
33
|
+
}),
|
|
34
|
+
...inspectionJobs(client),
|
|
35
|
+
queue: (queue: Pick<QueueDefinition, "name">) => inspectionOperation(() => client.getQueue(queue.name), queue.name),
|
|
36
|
+
schedules: (name?: string, key?: string) =>
|
|
37
|
+
inspectionOperation(() => {
|
|
38
|
+
if (client.getSchedules === undefined) {
|
|
39
|
+
throw new TypeError("This pg-boss client does not support getSchedules");
|
|
40
|
+
}
|
|
41
|
+
return client.getSchedules(name, key);
|
|
42
|
+
}),
|
|
43
|
+
schemaVersion: () =>
|
|
44
|
+
inspectionOperation(() => {
|
|
45
|
+
if (client.schemaVersion === undefined) {
|
|
46
|
+
throw new TypeError("This pg-boss client does not support schemaVersion");
|
|
47
|
+
}
|
|
48
|
+
return client.schemaVersion();
|
|
49
|
+
}),
|
|
50
|
+
snapshot: inspectionSnapshot(
|
|
51
|
+
() => client,
|
|
52
|
+
() => schema,
|
|
53
|
+
),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Effect, Schema } from "effect";
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
2
|
+
import { inspectionOperation } from "#server/adapters/inspectionOperation.ts";
|
|
3
|
+
import type { PgBossClient } from "#server/client.ts";
|
|
4
|
+
import type { PgBossError, PgBossPayloadError } from "#server/error.ts";
|
|
5
|
+
import type { SnapshotQueue, UnfinishedJob } from "#server/inspection.ts";
|
|
4
6
|
import { decodeStoredData, quotedSchema } from "#server/internal/storedRows.ts";
|
|
5
|
-
import { testingOperation } from "#server/internal/testingReadout.ts";
|
|
6
|
-
import type { SnapshotQueue, UnfinishedJob } from "#server/testing.ts";
|
|
7
7
|
|
|
8
8
|
const Rows = Schema.Array(
|
|
9
9
|
Schema.Struct({
|
|
@@ -15,29 +15,27 @@ const Rows = Schema.Array(
|
|
|
15
15
|
}),
|
|
16
16
|
);
|
|
17
17
|
|
|
18
|
-
export function
|
|
18
|
+
export function inspectionSnapshot(client: () => PgBossClient, schema: () => string) {
|
|
19
19
|
return <const TQueues extends readonly SnapshotQueue[]>(
|
|
20
20
|
queues: TQueues,
|
|
21
|
-
): Effect.Effect<
|
|
22
|
-
readonly UnfinishedJob<TQueues[number]>[],
|
|
23
|
-
PgBossPayloadError | PgBossTestingError,
|
|
24
|
-
TQueues[number]["schema"]["DecodingServices"]
|
|
25
|
-
> => {
|
|
21
|
+
): Effect.Effect<readonly UnfinishedJob<TQueues[number]>[], PgBossPayloadError | PgBossError, TQueues[number]["schema"]["DecodingServices"]> => {
|
|
26
22
|
const byName = new Map<string, TQueues[number]>(queues.map((queue) => [queue.name, queue]));
|
|
27
|
-
return
|
|
23
|
+
return inspectionOperation(async () => {
|
|
28
24
|
const quoted = quotedSchema(schema());
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
const db = client().getDb?.();
|
|
26
|
+
if (db === undefined) {
|
|
27
|
+
throw new TypeError("This pg-boss client does not support getDb");
|
|
28
|
+
}
|
|
29
|
+
const { rows } = await db.executeSql(
|
|
30
|
+
`SELECT id, name AS queue, data, start_after AS "startAfter",
|
|
33
31
|
CASE WHEN state = 'retry' AND started_on IS NULL AND start_after > ${quoted}.job_now()
|
|
34
32
|
AND output ? 'jobDeferral'
|
|
35
33
|
THEN 'deferred' ELSE state::text END AS state
|
|
36
34
|
FROM ${quoted}.job
|
|
37
35
|
WHERE name = ANY($1::text[]) AND state IN ('created', 'retry', 'active', 'failed')
|
|
38
36
|
ORDER BY created_on, id`,
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
[[...byName.keys()]],
|
|
38
|
+
);
|
|
41
39
|
return Schema.decodeUnknownPromise(Rows)(rows);
|
|
42
40
|
}).pipe(
|
|
43
41
|
Effect.flatMap((rows) =>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type Context, Effect } from "effect";
|
|
2
2
|
import type { PgBossClient } from "#server/client.ts";
|
|
3
3
|
import { toPgBossError } from "#server/error.ts";
|
|
4
|
-
import { deferralObservers } from "#server/internal/deferral.ts";
|
|
5
4
|
import type { JobEngine } from "#server/internal/engine.ts";
|
|
6
5
|
import { listJobs } from "./listJobs.ts";
|
|
7
6
|
import { queueAdministration } from "./queueAdministration.ts";
|
|
@@ -49,9 +48,6 @@ export function jobEngine(client: PgBossClient, schema = "pgboss"): Context.Serv
|
|
|
49
48
|
// Native batch settlement must not match a sibling's new claim at the unchanged retry count.
|
|
50
49
|
job.retryCount = Number.MAX_SAFE_INTEGER;
|
|
51
50
|
}
|
|
52
|
-
if (settled.deferred) {
|
|
53
|
-
deferralObservers.get(client)?.();
|
|
54
|
-
}
|
|
55
51
|
}),
|
|
56
52
|
),
|
|
57
53
|
),
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
export function payloadKey(parts: readonly string[], payload: object): string {
|
|
4
|
+
return JSON.stringify(parts.map((part) => [part, typeof Reflect.get(payload, part), String(Reflect.get(payload, part))]));
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function payloadJobId(queue: string, parts: readonly string[], payload: object): string {
|
|
8
|
+
const bytes = createHash("sha256")
|
|
9
|
+
.update(JSON.stringify([queue, payloadKey(parts, payload)]))
|
|
10
|
+
.digest();
|
|
11
|
+
bytes.writeUInt8((bytes.readUInt8(6) & 0x0f) | 0x80, 6);
|
|
12
|
+
bytes.writeUInt8((bytes.readUInt8(8) & 0x3f) | 0x80, 8);
|
|
13
|
+
const hex = bytes.subarray(0, 16).toString("hex");
|
|
14
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
15
|
+
}
|
|
@@ -4,9 +4,7 @@ import { testingExpirations } from "#server/adapters/testingExpirations.ts";
|
|
|
4
4
|
import type { ClientUpdateOptions, ClientUpdateRequest, ClientUpdateResult, PgBossClient } from "#server/client.ts";
|
|
5
5
|
import type { EngineClient } from "#server/engineClient.ts";
|
|
6
6
|
import type { EnqueueOptions } from "#server/enqueueOptions.ts";
|
|
7
|
-
import { deferralObservers } from "#server/internal/deferral.ts";
|
|
8
7
|
import type { TestingBatch, TestingWork } from "#server/internal/testingIdle.ts";
|
|
9
|
-
import { testingRegistration } from "#server/internal/testingRegistrations.ts";
|
|
10
8
|
import type { WorkerJob } from "#server/job.ts";
|
|
11
9
|
|
|
12
10
|
export interface TestingControls {
|
|
@@ -18,18 +16,9 @@ export interface TestingControls {
|
|
|
18
16
|
readonly work: TestingWork;
|
|
19
17
|
}
|
|
20
18
|
|
|
21
|
-
export function testingClient(client: EngineClient, schema: string, controls: TestingControls):
|
|
19
|
+
export function testingClient(client: EngineClient, schema: string, controls: TestingControls): EngineClient {
|
|
22
20
|
const engine = testingEngine(client, schema);
|
|
23
|
-
|
|
24
|
-
engine.observeSettlements((name) => {
|
|
25
|
-
for (const batch of controls.work.batches) {
|
|
26
|
-
if (batch.name === name) {
|
|
27
|
-
batch.settled = true;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
controls.changed();
|
|
31
|
-
}),
|
|
32
|
-
);
|
|
21
|
+
|
|
33
22
|
const expirations = testingExpirations(client);
|
|
34
23
|
function update(request: ClientUpdateRequest): Promise<ClientUpdateResult>;
|
|
35
24
|
function update(name: string, data: object | null | undefined, options?: ClientUpdateOptions): Promise<ClientUpdateResult>;
|
|
@@ -45,6 +34,9 @@ export function testingClient(client: EngineClient, schema: string, controls: Te
|
|
|
45
34
|
return result;
|
|
46
35
|
},
|
|
47
36
|
createQueue: (name, options) => {
|
|
37
|
+
if (options?.deadLetter !== undefined) {
|
|
38
|
+
controls.work.queues.add(name);
|
|
39
|
+
}
|
|
48
40
|
const { retryDelayMax, ...rest } = options ?? {};
|
|
49
41
|
return client.createQueue(name, {
|
|
50
42
|
...rest,
|
|
@@ -84,13 +76,6 @@ export function testingClient(client: EngineClient, schema: string, controls: Te
|
|
|
84
76
|
controls.changed();
|
|
85
77
|
return id;
|
|
86
78
|
},
|
|
87
|
-
stop: async (options) => {
|
|
88
|
-
try {
|
|
89
|
-
await client.stop(options);
|
|
90
|
-
} finally {
|
|
91
|
-
await Effect.runPromise(settlements.close);
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
79
|
update,
|
|
95
80
|
updateQueue: (name, options) =>
|
|
96
81
|
client.updateQueue(name, {
|
|
@@ -98,10 +83,9 @@ export function testingClient(client: EngineClient, schema: string, controls: Te
|
|
|
98
83
|
...controls.retryPolicy,
|
|
99
84
|
...(controls.retryPolicy.retryBackoff === false ? { retryDelayMax: null } : {}),
|
|
100
85
|
}),
|
|
101
|
-
work: async (name, options, handler) =>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const batch: TestingBatch = { name, settled: false };
|
|
86
|
+
work: async (name, options, handler) =>
|
|
87
|
+
client.work(name, options, async (jobs: readonly WorkerJob<unknown>[]) => {
|
|
88
|
+
const batch: TestingBatch = { jobs: new Map(jobs.map((job) => [job.id, job.retryCount])), name, settled: false };
|
|
105
89
|
controls.work.batches.add(batch);
|
|
106
90
|
controls.changed();
|
|
107
91
|
try {
|
|
@@ -121,14 +105,10 @@ export function testingClient(client: EngineClient, schema: string, controls: Te
|
|
|
121
105
|
controls.work.batches.delete(batch);
|
|
122
106
|
controls.changed();
|
|
123
107
|
}
|
|
124
|
-
})
|
|
125
|
-
},
|
|
108
|
+
}),
|
|
126
109
|
};
|
|
127
110
|
const wrapped = new Proxy(client, {
|
|
128
111
|
get(target, property) {
|
|
129
|
-
if (property === testingRegistration) {
|
|
130
|
-
return (name: string) => controls.work.queues.add(name);
|
|
131
|
-
}
|
|
132
112
|
if (Object.hasOwn(overrides, property)) {
|
|
133
113
|
const override: unknown = Reflect.get(overrides, property);
|
|
134
114
|
return override;
|
|
@@ -137,6 +117,5 @@ export function testingClient(client: EngineClient, schema: string, controls: Te
|
|
|
137
117
|
return typeof value === "function" ? value.bind(target) : value;
|
|
138
118
|
},
|
|
139
119
|
});
|
|
140
|
-
deferralObservers.set(wrapped, controls.changed);
|
|
141
120
|
return wrapped;
|
|
142
121
|
}
|