effect-mq 0.3.2 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -14
- package/dist/Job.d.ts +131 -9
- package/dist/Job.d.ts.map +1 -1
- package/dist/Job.js +81 -5
- package/dist/Job.js.map +1 -1
- package/dist/JobStore.d.ts +63 -2
- package/dist/JobStore.d.ts.map +1 -1
- package/dist/JobStore.js.map +1 -1
- package/dist/MemoryJobStore.d.ts.map +1 -1
- package/dist/MemoryJobStore.js +159 -119
- package/dist/MemoryJobStore.js.map +1 -1
- package/dist/Worker.d.ts +18 -0
- package/dist/Worker.d.ts.map +1 -1
- package/dist/Worker.js +37 -9
- package/dist/Worker.js.map +1 -1
- package/dist/drizzle-postgres/DrizzleJobStore.d.ts.map +1 -1
- package/dist/drizzle-postgres/DrizzleJobStore.js +239 -49
- package/dist/drizzle-postgres/DrizzleJobStore.js.map +1 -1
- package/dist/drizzle-postgres/schema.d.ts +35 -27
- package/dist/drizzle-postgres/schema.d.ts.map +1 -1
- package/dist/drizzle-postgres/schema.js +8 -2
- package/dist/drizzle-postgres/schema.js.map +1 -1
- package/dist/redis/RedisJobStore.d.ts.map +1 -1
- package/dist/redis/RedisJobStore.js +173 -36
- package/dist/redis/RedisJobStore.js.map +1 -1
- package/dist/redis/scripts.d.ts +24 -1
- package/dist/redis/scripts.d.ts.map +1 -1
- package/dist/redis/scripts.js +126 -21
- package/dist/redis/scripts.js.map +1 -1
- package/dist/testing/conformance.d.ts.map +1 -1
- package/dist/testing/conformance.js +266 -0
- package/dist/testing/conformance.js.map +1 -1
- package/package.json +1 -1
- package/src/Job.ts +268 -13
- package/src/JobStore.ts +77 -2
- package/src/MemoryJobStore.ts +102 -53
- package/src/Worker.ts +61 -9
- package/src/drizzle-postgres/DrizzleJobStore.ts +273 -66
- package/src/drizzle-postgres/schema.ts +33 -25
- package/src/redis/RedisJobStore.ts +236 -47
- package/src/redis/scripts.ts +153 -21
- package/src/testing/conformance.ts +350 -0
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
*/
|
|
34
34
|
import type * as JobStore from "../JobStore.ts";
|
|
35
35
|
import { type AnyPgColumnBuilder, type PgBuildExtraConfigColumns, type PgTableExtraConfigValue } from "drizzle-orm/pg-core";
|
|
36
|
+
type QueueName = JobStore.QueueName;
|
|
36
37
|
/**
|
|
37
38
|
* Table-factory options: `extraConfig` receives the table's columns (exactly
|
|
38
39
|
* like drizzle's third `pgTable` argument) and returns additional indexes,
|
|
@@ -43,10 +44,10 @@ import { type AnyPgColumnBuilder, type PgBuildExtraConfigColumns, type PgTableEx
|
|
|
43
44
|
export interface MqTableOptions<Columns extends Record<string, AnyPgColumnBuilder>> {
|
|
44
45
|
readonly extraConfig?: ((table: PgBuildExtraConfigColumns<Columns>) => Array<PgTableExtraConfigValue>) | undefined;
|
|
45
46
|
}
|
|
46
|
-
declare const jobsColumns: <JobName extends string>() => {
|
|
47
|
+
declare const jobsColumns: <JobName extends string, Queue extends string>() => {
|
|
47
48
|
id: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobStore.JobId>;
|
|
48
49
|
name: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobName>;
|
|
49
|
-
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>,
|
|
50
|
+
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, Queue>;
|
|
50
51
|
state: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobStore.JobState>;
|
|
51
52
|
priority: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgIntegerBuilder>>;
|
|
52
53
|
/** FIFO order within a priority; bumped on retry so retries go to the tail. */
|
|
@@ -61,6 +62,7 @@ declare const jobsColumns: <JobName extends string>() => {
|
|
|
61
62
|
timeoutMs: import("drizzle-orm/pg-core").PgBigInt53Builder;
|
|
62
63
|
cancelRequested: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgBooleanBuilder>>;
|
|
63
64
|
dedupeKey: import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>;
|
|
65
|
+
trace: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").PgJsonbBuilder, JobStore.TraceContext>;
|
|
64
66
|
runAt: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>;
|
|
65
67
|
enqueuedAt: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>;
|
|
66
68
|
processedAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
@@ -73,6 +75,8 @@ declare const jobsColumns: <JobName extends string>() => {
|
|
|
73
75
|
/**
|
|
74
76
|
* The jobs table factory. `JobName` types the `name` column — derive it from
|
|
75
77
|
* your job definitions: `mqJobs<typeof GenerateInvoice._tag | typeof Report._tag>()`.
|
|
78
|
+
* `Queue` types the `queue` column the same way — pass your own branded type
|
|
79
|
+
* or literal union (defaults to effect-mq's `QueueName` brand).
|
|
76
80
|
*
|
|
77
81
|
* `extend` adds your own columns (tenant ids, object ids, ...) to the table.
|
|
78
82
|
* At enqueue the Postgres store fills each extended column from the job's
|
|
@@ -93,7 +97,7 @@ declare const jobsColumns: <JobName extends string>() => {
|
|
|
93
97
|
*
|
|
94
98
|
* @since 0.1.0
|
|
95
99
|
*/
|
|
96
|
-
export declare const mqJobs: <JobName extends string = string, Extend extends Record<string, AnyPgColumnBuilder> = Record<never, never>>(tableName?: string, options?: MqTableOptions<ReturnType<typeof jobsColumns<JobName>> & Extend> & {
|
|
100
|
+
export declare const mqJobs: <JobName extends string = string, Queue extends string = QueueName, Extend extends Record<string, AnyPgColumnBuilder> = Record<never, never>>(tableName?: string, options?: MqTableOptions<ReturnType<typeof jobsColumns<JobName, Queue>> & Extend> & {
|
|
97
101
|
/** Extra columns appended to the factory's own (see the JSDoc example). */
|
|
98
102
|
readonly extend?: Extend | undefined;
|
|
99
103
|
}) => import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
@@ -102,7 +106,7 @@ export declare const mqJobs: <JobName extends string = string, Extend extends Re
|
|
|
102
106
|
columns: {
|
|
103
107
|
id: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobStore.JobId>;
|
|
104
108
|
name: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobName>;
|
|
105
|
-
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>,
|
|
109
|
+
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, Queue>;
|
|
106
110
|
state: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobStore.JobState>;
|
|
107
111
|
priority: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgIntegerBuilder>>;
|
|
108
112
|
/** FIFO order within a priority; bumped on retry so retries go to the tail. */
|
|
@@ -117,6 +121,7 @@ export declare const mqJobs: <JobName extends string = string, Extend extends Re
|
|
|
117
121
|
timeoutMs: import("drizzle-orm/pg-core").PgBigInt53Builder;
|
|
118
122
|
cancelRequested: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgBooleanBuilder>>;
|
|
119
123
|
dedupeKey: import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>;
|
|
124
|
+
trace: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").PgJsonbBuilder, JobStore.TraceContext>;
|
|
120
125
|
runAt: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>;
|
|
121
126
|
enqueuedAt: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTimestampBuilder>;
|
|
122
127
|
processedAt: import("drizzle-orm/pg-core").PgTimestampBuilder;
|
|
@@ -186,7 +191,7 @@ declare const attemptsColumns: (jobs: MqJobsTable) => {
|
|
|
186
191
|
*
|
|
187
192
|
* @since 0.1.0
|
|
188
193
|
*/
|
|
189
|
-
export declare const mqJobAttempts: (jobs:
|
|
194
|
+
export declare const mqJobAttempts: (jobs: MqJobsTable, tableName?: string, options?: MqTableOptions<ReturnType<typeof attemptsColumns>>) => import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
190
195
|
name: string;
|
|
191
196
|
schema: undefined;
|
|
192
197
|
columns: {
|
|
@@ -283,10 +288,10 @@ export declare const mqJobAttempts: (jobs: ReturnType<typeof mqJobs<any>>, table
|
|
|
283
288
|
};
|
|
284
289
|
dialect: 'pg';
|
|
285
290
|
}>;
|
|
286
|
-
declare const schedulesColumns: () => {
|
|
291
|
+
declare const schedulesColumns: <JobName extends string, Queue extends string>() => {
|
|
287
292
|
key: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobStore.ScheduleKey>;
|
|
288
|
-
jobName: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]
|
|
289
|
-
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>,
|
|
293
|
+
jobName: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobName>;
|
|
294
|
+
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, Queue>;
|
|
290
295
|
cron: import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>;
|
|
291
296
|
tz: import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>;
|
|
292
297
|
everyMs: import("drizzle-orm/pg-core").PgBigInt53Builder;
|
|
@@ -302,9 +307,12 @@ declare const schedulesColumns: () => {
|
|
|
302
307
|
/**
|
|
303
308
|
* Repeatable-job schedules (one row per `Job.schedule` key).
|
|
304
309
|
*
|
|
310
|
+
* `JobName` and `Queue` type the `jobName`/`queue` columns, exactly like
|
|
311
|
+
* `mqJobs` (both default to plain string / effect-mq's `QueueName` brand).
|
|
312
|
+
*
|
|
305
313
|
* @since 0.2.0
|
|
306
314
|
*/
|
|
307
|
-
export declare const mqSchedules: (tableName?: string, options?: MqTableOptions<ReturnType<typeof schedulesColumns
|
|
315
|
+
export declare const mqSchedules: <JobName extends string = string, Queue extends string = QueueName>(tableName?: string, options?: MqTableOptions<ReturnType<typeof schedulesColumns<JobName, Queue>>>) => import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
308
316
|
name: string;
|
|
309
317
|
schema: undefined;
|
|
310
318
|
columns: {
|
|
@@ -323,11 +331,11 @@ export declare const mqSchedules: (tableName?: string, options?: MqTableOptions<
|
|
|
323
331
|
identity: undefined;
|
|
324
332
|
generated: undefined;
|
|
325
333
|
}>;
|
|
326
|
-
jobName: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, {
|
|
334
|
+
jobName: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobName>, {
|
|
327
335
|
name: string;
|
|
328
336
|
tableName: string;
|
|
329
337
|
dataType: "string";
|
|
330
|
-
data:
|
|
338
|
+
data: JobName;
|
|
331
339
|
driverParam: string;
|
|
332
340
|
notNull: true;
|
|
333
341
|
hasDefault: false;
|
|
@@ -338,11 +346,11 @@ export declare const mqSchedules: (tableName?: string, options?: MqTableOptions<
|
|
|
338
346
|
identity: undefined;
|
|
339
347
|
generated: undefined;
|
|
340
348
|
}>;
|
|
341
|
-
queue: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>,
|
|
349
|
+
queue: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, Queue>, {
|
|
342
350
|
name: string;
|
|
343
351
|
tableName: string;
|
|
344
352
|
dataType: "string";
|
|
345
|
-
data:
|
|
353
|
+
data: Queue;
|
|
346
354
|
driverParam: string;
|
|
347
355
|
notNull: true;
|
|
348
356
|
hasDefault: false;
|
|
@@ -521,8 +529,8 @@ export declare const mqSchedules: (tableName?: string, options?: MqTableOptions<
|
|
|
521
529
|
};
|
|
522
530
|
dialect: 'pg';
|
|
523
531
|
}>;
|
|
524
|
-
declare const dedupeColumns: () => {
|
|
525
|
-
name: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]
|
|
532
|
+
declare const dedupeColumns: <JobName extends string>() => {
|
|
533
|
+
name: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobName>;
|
|
526
534
|
key: import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>;
|
|
527
535
|
jobId: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobStore.JobId>;
|
|
528
536
|
/** Set for ttl/throttle windows; NULL rows live as long as their job is pending. */
|
|
@@ -533,15 +541,15 @@ declare const dedupeColumns: () => {
|
|
|
533
541
|
*
|
|
534
542
|
* @since 0.3.0
|
|
535
543
|
*/
|
|
536
|
-
export declare const mqDedupe: (tableName?: string, options?: MqTableOptions<ReturnType<typeof dedupeColumns
|
|
544
|
+
export declare const mqDedupe: <JobName extends string = string>(tableName?: string, options?: MqTableOptions<ReturnType<typeof dedupeColumns<JobName>>>) => import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
537
545
|
name: string;
|
|
538
546
|
schema: undefined;
|
|
539
547
|
columns: {
|
|
540
|
-
name: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, {
|
|
548
|
+
name: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, JobName>, {
|
|
541
549
|
name: string;
|
|
542
550
|
tableName: string;
|
|
543
551
|
dataType: "string";
|
|
544
|
-
data:
|
|
552
|
+
data: JobName;
|
|
545
553
|
driverParam: string;
|
|
546
554
|
notNull: true;
|
|
547
555
|
hasDefault: false;
|
|
@@ -600,8 +608,8 @@ export declare const mqDedupe: (tableName?: string, options?: MqTableOptions<Ret
|
|
|
600
608
|
};
|
|
601
609
|
dialect: 'pg';
|
|
602
610
|
}>;
|
|
603
|
-
declare const queueControlColumns: () => {
|
|
604
|
-
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>,
|
|
611
|
+
declare const queueControlColumns: <Queue extends string>() => {
|
|
612
|
+
queue: import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, Queue>;
|
|
605
613
|
paused: import("drizzle-orm/pg-core").SetHasDefault<import("drizzle-orm/pg-core").SetNotNull<import("drizzle-orm/pg-core").PgBooleanBuilder>>;
|
|
606
614
|
};
|
|
607
615
|
/**
|
|
@@ -609,15 +617,15 @@ declare const queueControlColumns: () => {
|
|
|
609
617
|
*
|
|
610
618
|
* @since 0.2.0
|
|
611
619
|
*/
|
|
612
|
-
export declare const mqQueueControl: (tableName?: string, options?: MqTableOptions<ReturnType<typeof queueControlColumns
|
|
620
|
+
export declare const mqQueueControl: <Queue extends string = QueueName>(tableName?: string, options?: MqTableOptions<ReturnType<typeof queueControlColumns<Queue>>>) => import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
613
621
|
name: string;
|
|
614
622
|
schema: undefined;
|
|
615
623
|
columns: {
|
|
616
|
-
queue: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>,
|
|
624
|
+
queue: import("drizzle-orm/pg-core").PgBuildColumn<string, import("drizzle-orm/pg-core").Set$Type<import("drizzle-orm/pg-core").SetIsPrimaryKey<import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>>, Queue>, {
|
|
617
625
|
name: string;
|
|
618
626
|
tableName: string;
|
|
619
627
|
dataType: "string";
|
|
620
|
-
data:
|
|
628
|
+
data: Queue;
|
|
621
629
|
driverParam: string;
|
|
622
630
|
notNull: true;
|
|
623
631
|
hasDefault: false;
|
|
@@ -649,7 +657,7 @@ export declare const mqQueueControl: (tableName?: string, options?: MqTableOptio
|
|
|
649
657
|
/**
|
|
650
658
|
* @since 0.1.0
|
|
651
659
|
*/
|
|
652
|
-
export type MqJobsTable = ReturnType<typeof mqJobs<any>>;
|
|
660
|
+
export type MqJobsTable = ReturnType<typeof mqJobs<any, any>>;
|
|
653
661
|
/**
|
|
654
662
|
* @since 0.1.0
|
|
655
663
|
*/
|
|
@@ -657,14 +665,14 @@ export type MqJobAttemptsTable = ReturnType<typeof mqJobAttempts>;
|
|
|
657
665
|
/**
|
|
658
666
|
* @since 0.2.0
|
|
659
667
|
*/
|
|
660
|
-
export type MqSchedulesTable = ReturnType<typeof mqSchedules
|
|
668
|
+
export type MqSchedulesTable = ReturnType<typeof mqSchedules<any, any>>;
|
|
661
669
|
/**
|
|
662
670
|
* @since 0.2.0
|
|
663
671
|
*/
|
|
664
|
-
export type MqQueueControlTable = ReturnType<typeof mqQueueControl
|
|
672
|
+
export type MqQueueControlTable = ReturnType<typeof mqQueueControl<any>>;
|
|
665
673
|
/**
|
|
666
674
|
* @since 0.3.0
|
|
667
675
|
*/
|
|
668
|
-
export type MqDedupeTable = ReturnType<typeof mqDedupe
|
|
676
|
+
export type MqDedupeTable = ReturnType<typeof mqDedupe<any>>;
|
|
669
677
|
export {};
|
|
670
678
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/drizzle-postgres/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAE/C,OAAO,EACL,KAAK,kBAAkB,EAMvB,KAAK,yBAAyB,EAE9B,KAAK,uBAAuB,EAI7B,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/drizzle-postgres/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ const jobsColumns = () => ({
|
|
|
18
18
|
timeoutMs: bigint("timeout_ms", { mode: "number" }),
|
|
19
19
|
cancelRequested: boolean("cancel_requested").notNull().default(false),
|
|
20
20
|
dedupeKey: text("dedupe_key"),
|
|
21
|
+
trace: jsonb("trace").$type(),
|
|
21
22
|
runAt: timestamp("run_at", { withTimezone: true, mode: "date" }).notNull(),
|
|
22
23
|
enqueuedAt: timestamp("enqueued_at", { withTimezone: true, mode: "date" }).notNull(),
|
|
23
24
|
processedAt: timestamp("processed_at", { withTimezone: true, mode: "date" }),
|
|
@@ -30,6 +31,8 @@ const jobsColumns = () => ({
|
|
|
30
31
|
/**
|
|
31
32
|
* The jobs table factory. `JobName` types the `name` column — derive it from
|
|
32
33
|
* your job definitions: `mqJobs<typeof GenerateInvoice._tag | typeof Report._tag>()`.
|
|
34
|
+
* `Queue` types the `queue` column the same way — pass your own branded type
|
|
35
|
+
* or literal union (defaults to effect-mq's `QueueName` brand).
|
|
33
36
|
*
|
|
34
37
|
* `extend` adds your own columns (tenant ids, object ids, ...) to the table.
|
|
35
38
|
* At enqueue the Postgres store fills each extended column from the job's
|
|
@@ -96,7 +99,7 @@ export const mqJobAttempts = (jobs, tableName = "effect_mq_job_attempts", option
|
|
|
96
99
|
]);
|
|
97
100
|
const schedulesColumns = () => ({
|
|
98
101
|
key: text("key").primaryKey().$type(),
|
|
99
|
-
jobName: text("job_name").notNull(),
|
|
102
|
+
jobName: text("job_name").notNull().$type(),
|
|
100
103
|
queue: text("queue").notNull().$type(),
|
|
101
104
|
cron: text("cron"),
|
|
102
105
|
tz: text("tz"),
|
|
@@ -113,6 +116,9 @@ const schedulesColumns = () => ({
|
|
|
113
116
|
/**
|
|
114
117
|
* Repeatable-job schedules (one row per `Job.schedule` key).
|
|
115
118
|
*
|
|
119
|
+
* `JobName` and `Queue` type the `jobName`/`queue` columns, exactly like
|
|
120
|
+
* `mqJobs` (both default to plain string / effect-mq's `QueueName` brand).
|
|
121
|
+
*
|
|
116
122
|
* @since 0.2.0
|
|
117
123
|
*/
|
|
118
124
|
export const mqSchedules = (tableName = "effect_mq_schedules", options) => pgTable(tableName, schedulesColumns(), (table) => [
|
|
@@ -120,7 +126,7 @@ export const mqSchedules = (tableName = "effect_mq_schedules", options) => pgTab
|
|
|
120
126
|
...options?.extraConfig?.(table) ?? []
|
|
121
127
|
]);
|
|
122
128
|
const dedupeColumns = () => ({
|
|
123
|
-
name: text("name").notNull(),
|
|
129
|
+
name: text("name").notNull().$type(),
|
|
124
130
|
key: text("key").notNull(),
|
|
125
131
|
jobId: text("job_id").notNull().$type(),
|
|
126
132
|
/** Set for ttl/throttle windows; NULL rows live as long as their job is pending. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/drizzle-postgres/schema.ts"],"names":[],"mappings":"AAkCA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EAEL,MAAM,EACN,OAAO,EACP,KAAK,EACL,OAAO,EACP,KAAK,EAEL,OAAO,EAEP,UAAU,EACV,IAAI,EACJ,SAAS,EACV,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/drizzle-postgres/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RedisJobStore.d.ts","sourceRoot":"","sources":["../../src/redis/RedisJobStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAS,KAAK,OAAO,EAAY,QAAQ,EAAE,MAAM,EAAQ,KAAK,EAA2B,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC1H,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAA;AACnD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAG1C;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAA;IAC1D,gDAAgD;IAChD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;IAC1D;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAA;CACxD;
|
|
1
|
+
{"version":3,"file":"RedisJobStore.d.ts","sourceRoot":"","sources":["../../src/redis/RedisJobStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAS,KAAK,OAAO,EAAY,QAAQ,EAAE,MAAM,EAAQ,KAAK,EAA2B,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC1H,OAAO,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAA;AACnD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAA;AAG1C;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,eAAe,GAAG,SAAS,CAAA;IAC1D,gDAAgD;IAChD,QAAQ,CAAC,oBAAoB,CAAC,EAAE,QAAQ,CAAC,KAAK,GAAG,SAAS,CAAA;IAC1D;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,WAAW,GAAG,SAAS,CAAA;CACxD;AAsFD;;;;;GAKG;AACH,eAAO,MAAM,IAAI,aACL,oBAAoB,GAAG,SAAS,KACzC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAgrB/D,CAAA;AAEJ;;;;GAIG;AACH,eAAO,MAAM,KAAK,aACN,oBAAoB,GAAG,SAAS,KACzC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAmD,CAAA;AAEvG;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,OAAO,SACvB,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,YACnC,oBAAoB,GAAG,SAAS,KACzC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAuC,CAAA"}
|
|
@@ -55,6 +55,7 @@ const toRecord = (hash) => ({
|
|
|
55
55
|
timeoutMs: optionalNumber(hash.get("timeoutMs")),
|
|
56
56
|
cancelRequested: hash.get("cancelRequested") === "1",
|
|
57
57
|
dedupeKey: optionalString(hash.get("dedupeKey")),
|
|
58
|
+
trace: optionalJson(hash.get("trace")),
|
|
58
59
|
runAt: Number(hash.get("runAt") ?? 0),
|
|
59
60
|
enqueuedAt: Number(hash.get("enqueuedAt") ?? 0),
|
|
60
61
|
processedAt: optionalNumber(hash.get("processedAt")),
|
|
@@ -116,6 +117,8 @@ export const make = (options) => Effect.gen(function* () {
|
|
|
116
117
|
const evalListSchedules = redis.eval(scripts.listSchedules);
|
|
117
118
|
const evalDueSchedules = redis.eval(scripts.dueSchedules);
|
|
118
119
|
const evalAdvanceSchedule = redis.eval(scripts.advanceSchedule);
|
|
120
|
+
const evalTickSchedule = redis.eval(scripts.tickSchedule);
|
|
121
|
+
const evalEnqueueMany = redis.eval(scripts.enqueueMany);
|
|
119
122
|
const evalSweepState = redis.eval(scripts.sweepState);
|
|
120
123
|
const evalSweepDedupes = redis.eval(scripts.sweepDedupes);
|
|
121
124
|
// Wake protocol: a queue-filtered waiter registry (same-process wake-ups
|
|
@@ -192,40 +195,160 @@ export const make = (options) => Effect.gen(function* () {
|
|
|
192
195
|
const raw = generate(request);
|
|
193
196
|
return Effect.isEffect(raw) ? raw : Effect.succeed(raw);
|
|
194
197
|
});
|
|
195
|
-
const enqueueOnce = (request, idMode, id, now) => evalEnqueue(prefix, idMode, id, request.name, request.queue, JSON.stringify(request.payload ?? null), JSON.stringify(request.metadata), request.priority, request.attemptsMax, request.backoff === undefined ? "" : JSON.stringify(request.backoff), request.keep === undefined ? "" : JSON.stringify(request.keep), request.timeoutMs === undefined ? "" : String(request.timeoutMs), Math.max(0, request.delayMs), now, request.dedupe?.key ?? "", request.dedupe?.ttlMs === undefined ? "" : String(request.dedupe.ttlMs), request.dedupe?.extend === true ? "1" : "0", request.dedupe?.replace === true ? "1" : "0");
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
const enqueueOnce = (request, idMode, id, now) => evalEnqueue(prefix, idMode, id, request.name, request.queue, JSON.stringify(request.payload ?? null), JSON.stringify(request.metadata), request.priority, request.attemptsMax, request.backoff === undefined ? "" : JSON.stringify(request.backoff), request.keep === undefined ? "" : JSON.stringify(request.keep), request.timeoutMs === undefined ? "" : String(request.timeoutMs), Math.max(0, request.delayMs), now, request.dedupe?.key ?? "", request.dedupe?.ttlMs === undefined ? "" : String(request.dedupe.ttlMs), request.dedupe?.extend === true ? "1" : "0", request.dedupe?.replace === true ? "1" : "0", request.trace === undefined ? "" : JSON.stringify(request.trace));
|
|
199
|
+
// Shared by cancel and cancelByDedupe.
|
|
200
|
+
const cancelJob = (id) => Effect.gen(function* () {
|
|
201
|
+
const now = yield* Clock.currentTimeMillis;
|
|
202
|
+
const reply = JSON.parse(yield* evalCancel(prefix, id, now).pipe(Effect.mapError(storeError("cancel failed"))));
|
|
203
|
+
if (reply.error === "notfound")
|
|
204
|
+
return yield* new JobStore.JobNotFoundError({ jobId: id });
|
|
205
|
+
if (reply.error === "state") {
|
|
206
|
+
return yield* new JobStore.JobNotCancellableError({ jobId: id, state: reply.state ?? "completed" });
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
const enqueueJob = (request) => Effect.gen(function* () {
|
|
210
|
+
const now = yield* Clock.currentTimeMillis;
|
|
211
|
+
const generate = options?.idGenerator;
|
|
212
|
+
for (let i = 0; i < 5; i++) {
|
|
213
|
+
const mode = request.id !== undefined
|
|
214
|
+
? "user"
|
|
215
|
+
: generate !== undefined
|
|
216
|
+
? "generated"
|
|
217
|
+
: "auto";
|
|
218
|
+
const candidate = mode === "user"
|
|
219
|
+
? request.id ?? ""
|
|
220
|
+
: mode === "generated" && generate !== undefined
|
|
221
|
+
? yield* generateCandidate(request, generate)
|
|
222
|
+
: "";
|
|
223
|
+
const reply = JSON.parse(yield* enqueueOnce(request, mode, candidate, now));
|
|
224
|
+
if (reply.collision === true)
|
|
225
|
+
continue;
|
|
226
|
+
if (reply.error !== undefined || reply.id === undefined) {
|
|
227
|
+
return yield* new JobStore.JobStoreError({
|
|
228
|
+
message: "enqueue failed: could not generate a unique job id"
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
if (reply.wake === true) {
|
|
232
|
+
// A replace-while-delayed reply names the keyed job's queue.
|
|
233
|
+
yield* wakeUp(reply.queue !== undefined ? JobStore.QueueName(reply.queue) : request.queue);
|
|
234
|
+
}
|
|
235
|
+
return { id: JobStore.JobId(reply.id), duplicate: reply.duplicate === true };
|
|
236
|
+
}
|
|
237
|
+
return yield* new JobStore.JobStoreError({
|
|
238
|
+
message: "enqueue failed: could not generate a unique job id"
|
|
239
|
+
});
|
|
240
|
+
}).pipe(Effect.mapError((error) => error instanceof JobStore.JobStoreError ? error : storeError("enqueue failed")(error)));
|
|
241
|
+
// One EVALSHA per chunk of plain (non-dedup) items. Ids resolve in-script
|
|
242
|
+
// ("auto") or client-side (user/generated); a generated id that collides
|
|
243
|
+
// re-draws and retries in the next round, like the single-enqueue path.
|
|
244
|
+
const insertBatch = (requests) => Effect.gen(function* () {
|
|
245
|
+
const generate = options?.idGenerator;
|
|
246
|
+
const results = requests.map(() => undefined);
|
|
247
|
+
let pending = requests.map((request, index) => ({ request, index }));
|
|
248
|
+
for (let round = 0; round < 5 && pending.length > 0; round++) {
|
|
198
249
|
const now = yield* Clock.currentTimeMillis;
|
|
199
|
-
const
|
|
200
|
-
for (let
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
250
|
+
const stillPending = [];
|
|
251
|
+
for (let start = 0; start < pending.length; start += 500) {
|
|
252
|
+
const chunk = pending.slice(start, start + 500);
|
|
253
|
+
const itemArgs = [];
|
|
254
|
+
for (const { request } of chunk) {
|
|
255
|
+
const mode = request.id !== undefined
|
|
256
|
+
? "user"
|
|
257
|
+
: generate !== undefined
|
|
258
|
+
? "generated"
|
|
259
|
+
: "auto";
|
|
260
|
+
const candidate = request.id !== undefined
|
|
261
|
+
? request.id
|
|
262
|
+
: generate !== undefined
|
|
263
|
+
? yield* generateCandidate(request, generate)
|
|
264
|
+
: "";
|
|
265
|
+
itemArgs.push(mode, candidate, request.name, request.queue, JSON.stringify(request.payload ?? null), JSON.stringify(request.metadata), String(request.priority), String(request.attemptsMax), request.backoff === undefined ? "" : JSON.stringify(request.backoff), request.keep === undefined ? "" : JSON.stringify(request.keep), request.timeoutMs === undefined ? "" : String(request.timeoutMs), request.trace === undefined ? "" : JSON.stringify(request.trace), String(Math.max(0, request.delayMs)));
|
|
266
|
+
}
|
|
267
|
+
const replies = JSON
|
|
268
|
+
.parse(yield* evalEnqueueMany(prefix, now, chunk.length, itemArgs));
|
|
269
|
+
const freshQueues = new Set();
|
|
270
|
+
let failed = false;
|
|
271
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
272
|
+
const reply = replies[i];
|
|
273
|
+
const item = chunk[i];
|
|
274
|
+
if (item === undefined)
|
|
275
|
+
continue;
|
|
276
|
+
if (reply === undefined || reply.error !== undefined) {
|
|
277
|
+
failed = true;
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (reply.collision === true) {
|
|
281
|
+
// Generated-id collision: re-draw and re-insert next round.
|
|
282
|
+
// NOTE this lands the item after its batch-mates in FIFO
|
|
283
|
+
// order — acceptable for a pathological collision, and
|
|
284
|
+
// documented on the contract.
|
|
285
|
+
stillPending.push(item);
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (reply.id === undefined) {
|
|
289
|
+
failed = true;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
results[item.index] = { id: JobStore.JobId(reply.id), duplicate: reply.duplicate === true };
|
|
293
|
+
if (reply.duplicate !== true) {
|
|
294
|
+
freshQueues.add(item.request.queue);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// The script is not transactional across items: inserts that
|
|
298
|
+
// landed before a failing item are durable, so wake their queues
|
|
299
|
+
// BEFORE surfacing the error.
|
|
300
|
+
for (const queue of freshQueues) {
|
|
301
|
+
yield* wakeUp(queue);
|
|
302
|
+
}
|
|
303
|
+
if (failed) {
|
|
215
304
|
return yield* new JobStore.JobStoreError({
|
|
216
|
-
message: "
|
|
305
|
+
message: "enqueueMany failed: could not generate a unique job id"
|
|
217
306
|
});
|
|
218
307
|
}
|
|
219
|
-
if (reply.wake === true) {
|
|
220
|
-
// A replace-while-delayed reply names the keyed job's queue.
|
|
221
|
-
yield* wakeUp(reply.queue !== undefined ? JobStore.QueueName(reply.queue) : request.queue);
|
|
222
|
-
}
|
|
223
|
-
return { id: JobStore.JobId(reply.id), duplicate: reply.duplicate === true };
|
|
224
308
|
}
|
|
225
|
-
|
|
226
|
-
|
|
309
|
+
pending = stillPending;
|
|
310
|
+
}
|
|
311
|
+
const resolved = [];
|
|
312
|
+
for (const result of results) {
|
|
313
|
+
if (result === undefined) {
|
|
314
|
+
return yield* new JobStore.JobStoreError({
|
|
315
|
+
message: "enqueueMany failed: could not generate a unique job id"
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
resolved.push(result);
|
|
319
|
+
}
|
|
320
|
+
return resolved;
|
|
321
|
+
}).pipe(Effect.mapError((error) => error instanceof JobStore.JobStoreError ? error : storeError("enqueueMany failed")(error)));
|
|
322
|
+
const store = {
|
|
323
|
+
enqueue: enqueueJob,
|
|
324
|
+
enqueueMany: (requests) => Effect.gen(function* () {
|
|
325
|
+
const results = [];
|
|
326
|
+
let batch = [];
|
|
327
|
+
const flush = () => Effect.gen(function* () {
|
|
328
|
+
if (batch.length === 0)
|
|
329
|
+
return;
|
|
330
|
+
const items = batch;
|
|
331
|
+
batch = [];
|
|
332
|
+
// No spread: a six-figure batch would blow the engine's
|
|
333
|
+
// argument-count limit after the rows already committed.
|
|
334
|
+
for (const result of yield* insertBatch(items)) {
|
|
335
|
+
results.push(result);
|
|
336
|
+
}
|
|
227
337
|
});
|
|
228
|
-
|
|
338
|
+
for (const request of requests) {
|
|
339
|
+
// Dedup items run through the single-enqueue decision tree in
|
|
340
|
+
// order; runs of plain items between them batch into one script.
|
|
341
|
+
if (request.dedupe !== undefined) {
|
|
342
|
+
yield* flush();
|
|
343
|
+
results.push(yield* enqueueJob(request));
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
batch.push(request);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
yield* flush();
|
|
350
|
+
return results;
|
|
351
|
+
}),
|
|
229
352
|
claim: (claimOptions) =>
|
|
230
353
|
// Snapshot BEFORE the script runs: a wake that fires while the claim
|
|
231
354
|
// executes must make awaitWake(token) return immediately.
|
|
@@ -368,14 +491,15 @@ export const make = (options) => Effect.gen(function* () {
|
|
|
368
491
|
return totals;
|
|
369
492
|
})),
|
|
370
493
|
remove: (id) => evalRemove(prefix, id).pipe(Effect.mapError(storeError("remove failed")), Effect.map((raw) => raw !== "0")),
|
|
371
|
-
cancel: (id) =>
|
|
372
|
-
|
|
373
|
-
const
|
|
374
|
-
if (
|
|
375
|
-
return
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
494
|
+
cancel: (id) => cancelJob(id),
|
|
495
|
+
cancelByDedupe: (name, key) => Effect.gen(function* () {
|
|
496
|
+
const jobId = yield* redis.send("HGET", `${prefix}:dedupe:${name}\u0000${key}`, "jobId").pipe(Effect.mapError(storeError("cancelByDedupe failed")));
|
|
497
|
+
if (jobId === null || jobId === undefined || jobId === "")
|
|
498
|
+
return false;
|
|
499
|
+
return yield* cancelJob(JobStore.JobId(String(jobId))).pipe(Effect.as(true),
|
|
500
|
+
// Idempotent: a vanished or already-terminal keyed job is
|
|
501
|
+
// "nothing pending", not an error.
|
|
502
|
+
Effect.catchTag(["JobNotFoundError", "JobNotCancellableError"], () => Effect.succeed(false)));
|
|
379
503
|
}),
|
|
380
504
|
promote: (id) => Effect.gen(function* () {
|
|
381
505
|
const now = yield* Clock.currentTimeMillis;
|
|
@@ -405,6 +529,19 @@ export const make = (options) => Effect.gen(function* () {
|
|
|
405
529
|
const flat = JSON.parse(yield* evalDueSchedules(prefix, now));
|
|
406
530
|
return flat.map((pairs) => toSchedule(foldPairs(pairs)));
|
|
407
531
|
}).pipe(Effect.mapError(storeError("dueSchedules failed"))),
|
|
532
|
+
tickSchedule: (key, expectedRunAt, nextRunAt, request) => Effect.gen(function* () {
|
|
533
|
+
if (request.id === undefined) {
|
|
534
|
+
return yield* new JobStore.JobStoreError({
|
|
535
|
+
message: "tickSchedule requires an explicit request.id"
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
const now = yield* Clock.currentTimeMillis;
|
|
539
|
+
const fired = (yield* evalTickSchedule(prefix, key, expectedRunAt, nextRunAt, request.id, request.name, request.queue, JSON.stringify(request.payload ?? null), JSON.stringify(request.metadata), request.priority, request.attemptsMax, request.backoff === undefined ? "" : JSON.stringify(request.backoff), request.keep === undefined ? "" : JSON.stringify(request.keep), request.timeoutMs === undefined ? "" : String(request.timeoutMs), request.trace === undefined ? "" : JSON.stringify(request.trace), Math.max(0, request.delayMs), now)) === "1";
|
|
540
|
+
if (fired) {
|
|
541
|
+
yield* wakeUp(request.queue);
|
|
542
|
+
}
|
|
543
|
+
return fired;
|
|
544
|
+
}).pipe(Effect.mapError((error) => error instanceof JobStore.JobStoreError ? error : storeError("tickSchedule failed")(error))),
|
|
408
545
|
advanceSchedule: (key, expectedRunAt, nextRunAt) => evalAdvanceSchedule(prefix, key, expectedRunAt, nextRunAt).pipe(Effect.mapError(storeError("advanceSchedule failed")), Effect.asVoid)
|
|
409
546
|
};
|
|
410
547
|
return store;
|