pg-boss 12.5.1 → 12.5.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/dist/boss.d.ts +1 -1
- package/dist/boss.d.ts.map +1 -1
- package/dist/boss.js +22 -12
- package/dist/manager.js +8 -8
- package/dist/plans.d.ts +9 -5
- package/dist/plans.d.ts.map +1 -1
- package/dist/plans.js +45 -27
- package/package.json +1 -1
package/dist/boss.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ declare class Boss extends EventEmitter implements types.EventsMixin {
|
|
|
10
10
|
constructor(db: types.IDatabase, manager: Manager, config: types.ResolvedConstructorOptions);
|
|
11
11
|
start(): Promise<void>;
|
|
12
12
|
stop(): Promise<void>;
|
|
13
|
-
supervise(value?: string | types.QueueResult): Promise<void>;
|
|
13
|
+
supervise(value?: string | types.QueueResult[]): Promise<void>;
|
|
14
14
|
}
|
|
15
15
|
export default Boss;
|
|
16
16
|
//# sourceMappingURL=boss.d.ts.map
|
package/dist/boss.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boss.d.ts","sourceRoot":"","sources":["../src/boss.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAYnC,cAAM,IAAK,SAAQ,YAAa,YAAW,KAAK,CAAC,WAAW;;IAQ1D,MAAM;;;MAAS;gBAGb,EAAE,EAAE,KAAK,CAAC,SAAS,EACnB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,KAAK,CAAC,0BAA0B;IAkBpC,KAAK;IAUL,IAAI;
|
|
1
|
+
{"version":3,"file":"boss.d.ts","sourceRoot":"","sources":["../src/boss.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,aAAa,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AAGvC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AAYnC,cAAM,IAAK,SAAQ,YAAa,YAAW,KAAK,CAAC,WAAW;;IAQ1D,MAAM;;;MAAS;gBAGb,EAAE,EAAE,KAAK,CAAC,SAAS,EACnB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,KAAK,CAAC,0BAA0B;IAkBpC,KAAK;IAUL,IAAI;IAiEJ,SAAS,CAAE,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,EAAE;CAwEtD;AAED,eAAe,IAAI,CAAA"}
|
package/dist/boss.js
CHANGED
|
@@ -44,16 +44,28 @@ class Boss extends EventEmitter {
|
|
|
44
44
|
this.#stopped = true;
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
-
async #executeSql(sql
|
|
47
|
+
async #executeSql(sql) {
|
|
48
48
|
const started = Date.now();
|
|
49
|
-
const result = unwrapSQLResult(await this.#db.executeSql(sql
|
|
50
|
-
const
|
|
51
|
-
const elapsed = (ended - started) / 1000;
|
|
49
|
+
const result = unwrapSQLResult(await this.#db.executeSql(sql));
|
|
50
|
+
const elapsed = (Date.now() - started) / 1000;
|
|
52
51
|
if (elapsed > WARNINGS.SLOW_QUERY.seconds ||
|
|
53
52
|
this.#config.__test__warn_slow_query) {
|
|
54
53
|
this.emit(events.warning, {
|
|
55
54
|
message: WARNINGS.SLOW_QUERY.message,
|
|
56
|
-
data: { elapsed, sql
|
|
55
|
+
data: { elapsed, sql },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
async #executeQuery(query) {
|
|
61
|
+
const started = Date.now();
|
|
62
|
+
const result = unwrapSQLResult(await this.#db.executeSql(query.text, query.values));
|
|
63
|
+
const elapsed = (Date.now() - started) / 1000;
|
|
64
|
+
if (elapsed > WARNINGS.SLOW_QUERY.seconds ||
|
|
65
|
+
this.#config.__test__warn_slow_query) {
|
|
66
|
+
this.emit(events.warning, {
|
|
67
|
+
message: WARNINGS.SLOW_QUERY.message,
|
|
68
|
+
data: { elapsed, sql: query.text, values: query.values },
|
|
57
69
|
});
|
|
58
70
|
}
|
|
59
71
|
return result;
|
|
@@ -69,9 +81,7 @@ class Boss extends EventEmitter {
|
|
|
69
81
|
}
|
|
70
82
|
this.#maintaining = true;
|
|
71
83
|
const queues = await this.#manager.getQueues();
|
|
72
|
-
|
|
73
|
-
!this.#stopped && (await this.supervise(queue));
|
|
74
|
-
}
|
|
84
|
+
!this.#stopped && (await this.supervise(queues));
|
|
75
85
|
}
|
|
76
86
|
catch (err) {
|
|
77
87
|
this.emit(events.error, err);
|
|
@@ -82,8 +92,8 @@ class Boss extends EventEmitter {
|
|
|
82
92
|
}
|
|
83
93
|
async supervise(value) {
|
|
84
94
|
let queues;
|
|
85
|
-
if (
|
|
86
|
-
queues =
|
|
95
|
+
if (Array.isArray(value)) {
|
|
96
|
+
queues = value;
|
|
87
97
|
}
|
|
88
98
|
else {
|
|
89
99
|
queues = await this.#manager.getQueues(value);
|
|
@@ -106,7 +116,7 @@ class Boss extends EventEmitter {
|
|
|
106
116
|
}
|
|
107
117
|
async #monitor(table, names) {
|
|
108
118
|
const command = plans.trySetQueueMonitorTime(this.#config.schema, names, this.#config.monitorIntervalSeconds);
|
|
109
|
-
const { rows } = await this.#
|
|
119
|
+
const { rows } = await this.#executeQuery(command);
|
|
110
120
|
if (rows.length) {
|
|
111
121
|
const queues = rows.map((q) => q.name);
|
|
112
122
|
const cacheStatsSql = plans.cacheQueueStats(this.#config.schema, table, queues);
|
|
@@ -124,7 +134,7 @@ class Boss extends EventEmitter {
|
|
|
124
134
|
}
|
|
125
135
|
async #maintain(table, names) {
|
|
126
136
|
const command = plans.trySetQueueDeletionTime(this.#config.schema, names, this.#config.maintenanceIntervalSeconds);
|
|
127
|
-
const { rows } = await this.#
|
|
137
|
+
const { rows } = await this.#executeQuery(command);
|
|
128
138
|
if (rows.length) {
|
|
129
139
|
const queues = rows.map((q) => q.name);
|
|
130
140
|
const sql = plans.deletion(this.#config.schema, table, queues);
|
package/dist/manager.js
CHANGED
|
@@ -340,10 +340,10 @@ class Manager extends EventEmitter {
|
|
|
340
340
|
limit: options.batchSize || 1,
|
|
341
341
|
ignoreSingletons: singletonsActive
|
|
342
342
|
};
|
|
343
|
-
const
|
|
343
|
+
const query = plans.fetchNextJob(fetchOptions);
|
|
344
344
|
let result;
|
|
345
345
|
try {
|
|
346
|
-
result = await db.executeSql(
|
|
346
|
+
result = await db.executeSql(query.text, query.values);
|
|
347
347
|
}
|
|
348
348
|
catch (err) {
|
|
349
349
|
// errors from fetchquery should only be unique constraint violations
|
|
@@ -448,8 +448,8 @@ class Manager extends EventEmitter {
|
|
|
448
448
|
Attorney.assertQueueName(name);
|
|
449
449
|
}
|
|
450
450
|
}
|
|
451
|
-
const
|
|
452
|
-
const { rows } = await this.db.executeSql(
|
|
451
|
+
const query = plans.getQueues(this.config.schema, names);
|
|
452
|
+
const { rows } = await this.db.executeSql(query.text, query.values);
|
|
453
453
|
return rows;
|
|
454
454
|
}
|
|
455
455
|
async updateQueue(name, options = {}) {
|
|
@@ -472,8 +472,8 @@ class Manager extends EventEmitter {
|
|
|
472
472
|
}
|
|
473
473
|
async getQueue(name) {
|
|
474
474
|
Attorney.assertQueueName(name);
|
|
475
|
-
const
|
|
476
|
-
const { rows } = await this.db.executeSql(
|
|
475
|
+
const query = plans.getQueues(this.config.schema, [name]);
|
|
476
|
+
const { rows } = await this.db.executeSql(query.text, query.values);
|
|
477
477
|
return rows[0] || null;
|
|
478
478
|
}
|
|
479
479
|
async deleteQueue(name) {
|
|
@@ -517,8 +517,8 @@ class Manager extends EventEmitter {
|
|
|
517
517
|
async getQueueStats(name) {
|
|
518
518
|
Attorney.assertQueueName(name);
|
|
519
519
|
const queue = await this.getQueueCache(name);
|
|
520
|
-
const
|
|
521
|
-
const { rows } = await this.db.executeSql(
|
|
520
|
+
const query = plans.getQueueStats(this.config.schema, queue.table, [name]);
|
|
521
|
+
const { rows } = await this.db.executeSql(query.text, query.values);
|
|
522
522
|
return Object.assign(queue, rows.at(0) || {});
|
|
523
523
|
}
|
|
524
524
|
async getJobById(name, id, options = {}) {
|
package/dist/plans.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { UpdateQueueOptions } from './types.ts';
|
|
2
|
+
export interface SqlQuery {
|
|
3
|
+
text: string;
|
|
4
|
+
values: unknown[];
|
|
5
|
+
}
|
|
2
6
|
declare const DEFAULT_SCHEMA = "pgboss";
|
|
3
7
|
declare const MIGRATE_RACE_MESSAGE = "division by zero";
|
|
4
8
|
declare const CREATE_RACE_MESSAGE = "already exists";
|
|
@@ -22,11 +26,11 @@ declare function create(schema: string, version: number, options?: {
|
|
|
22
26
|
}): string;
|
|
23
27
|
declare function createQueue(schema: string, name: string, options: unknown): string;
|
|
24
28
|
declare function deleteQueue(schema: string, name: string): string;
|
|
25
|
-
declare function trySetQueueMonitorTime(schema: string, queues: string[], seconds: number):
|
|
26
|
-
declare function trySetQueueDeletionTime(schema: string, queues: string[], seconds: number):
|
|
29
|
+
declare function trySetQueueMonitorTime(schema: string, queues: string[], seconds: number): SqlQuery;
|
|
30
|
+
declare function trySetQueueDeletionTime(schema: string, queues: string[], seconds: number): SqlQuery;
|
|
27
31
|
declare function trySetCronTime(schema: string, seconds: number): string;
|
|
28
32
|
declare function updateQueue(schema: string, { deadLetter }?: UpdateQueueOptions): string;
|
|
29
|
-
declare function getQueues(schema: string, names?: string[]):
|
|
33
|
+
declare function getQueues(schema: string, names?: string[]): SqlQuery;
|
|
30
34
|
declare function deleteJobsById(schema: string, table: string): string;
|
|
31
35
|
declare function deleteQueuedJobs(schema: string, table: string): string;
|
|
32
36
|
declare function deleteStoredJobs(schema: string, table: string): string;
|
|
@@ -55,7 +59,7 @@ interface FetchJobOptions {
|
|
|
55
59
|
ignoreStartAfter?: boolean;
|
|
56
60
|
ignoreSingletons: string[] | null;
|
|
57
61
|
}
|
|
58
|
-
declare function fetchNextJob({ schema, table, name, policy, limit, includeMetadata, priority, ignoreStartAfter, ignoreSingletons }: FetchJobOptions):
|
|
62
|
+
declare function fetchNextJob({ schema, table, name, policy, limit, includeMetadata, priority, ignoreStartAfter, ignoreSingletons }: FetchJobOptions): SqlQuery;
|
|
59
63
|
declare function completeJobs(schema: string, table: string): string;
|
|
60
64
|
declare function cancelJobs(schema: string, table: string): string;
|
|
61
65
|
declare function resumeJobs(schema: string, table: string): string;
|
|
@@ -69,7 +73,7 @@ declare function failJobsById(schema: string, table: string): string;
|
|
|
69
73
|
declare function failJobsByTimeout(schema: string, table: string, queues: string[]): string;
|
|
70
74
|
declare function deletion(schema: string, table: string, queues: string[]): string;
|
|
71
75
|
declare function retryJobs(schema: string, table: string): string;
|
|
72
|
-
declare function getQueueStats(schema: string, table: string, queues: string[]):
|
|
76
|
+
declare function getQueueStats(schema: string, table: string, queues: string[]): SqlQuery;
|
|
73
77
|
declare function cacheQueueStats(schema: string, table: string, queues: string[]): string;
|
|
74
78
|
declare function locked(schema: string, query: string | string[], key?: string): string;
|
|
75
79
|
declare function assertMigration(schema: string, version: number): string;
|
package/dist/plans.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD,QAAA,MAAM,cAAc,WAAW,CAAA;AAC/B,QAAA,MAAM,oBAAoB,qBAAqB,CAAA;AAC/C,QAAA,MAAM,mBAAmB,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"plans.d.ts","sourceRoot":"","sources":["../src/plans.ts"],"names":[],"mappings":"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"}
|
package/dist/plans.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const DEFAULT_SCHEMA = 'pgboss';
|
|
2
2
|
const MIGRATE_RACE_MESSAGE = 'division by zero';
|
|
3
3
|
const CREATE_RACE_MESSAGE = 'already exists';
|
|
4
|
+
const SINGLE_QUOTE_REGEX = /'/g;
|
|
4
5
|
const FIFTEEN_MINUTES = 60 * 15;
|
|
5
6
|
const FORTEEN_DAYS = 60 * 60 * 24 * 14;
|
|
6
7
|
const SEVEN_DAYS = 60 * 60 * 24 * 7;
|
|
@@ -357,13 +358,16 @@ function trySetTimestamp(schema, column, seconds) {
|
|
|
357
358
|
`;
|
|
358
359
|
}
|
|
359
360
|
function trySetQueueTimestamp(schema, queues, column, seconds) {
|
|
360
|
-
return
|
|
361
|
+
return {
|
|
362
|
+
text: `
|
|
361
363
|
UPDATE ${schema}.queue
|
|
362
364
|
SET ${column} = now()
|
|
363
|
-
WHERE name
|
|
365
|
+
WHERE name = ANY($1::text[])
|
|
364
366
|
AND EXTRACT( EPOCH FROM (now() - COALESCE(${column}, now() - interval '1 week') ) ) > ${seconds}
|
|
365
|
-
RETURNING name
|
|
366
|
-
|
|
367
|
+
RETURNING name
|
|
368
|
+
`,
|
|
369
|
+
values: [queues]
|
|
370
|
+
};
|
|
367
371
|
}
|
|
368
372
|
function updateQueue(schema, { deadLetter } = {}) {
|
|
369
373
|
return `
|
|
@@ -388,8 +392,10 @@ function updateQueue(schema, { deadLetter } = {}) {
|
|
|
388
392
|
`;
|
|
389
393
|
}
|
|
390
394
|
function getQueues(schema, names) {
|
|
391
|
-
|
|
392
|
-
|
|
395
|
+
const hasNames = names && names.length > 0;
|
|
396
|
+
return {
|
|
397
|
+
text: `
|
|
398
|
+
SELECT
|
|
393
399
|
q.name,
|
|
394
400
|
q.policy,
|
|
395
401
|
q.retry_limit as "retryLimit",
|
|
@@ -411,8 +417,10 @@ function getQueues(schema, names) {
|
|
|
411
417
|
q.created_on as "createdOn",
|
|
412
418
|
q.updated_on as "updatedOn"
|
|
413
419
|
FROM ${schema}.queue q
|
|
414
|
-
${
|
|
415
|
-
|
|
420
|
+
${hasNames ? 'WHERE q.name = ANY($1::text[])' : ''}
|
|
421
|
+
`,
|
|
422
|
+
values: hasNames ? [names] : []
|
|
423
|
+
};
|
|
416
424
|
}
|
|
417
425
|
function deleteJobsById(schema, table) {
|
|
418
426
|
return `
|
|
@@ -502,14 +510,16 @@ function insertVersion(schema, version) {
|
|
|
502
510
|
function fetchNextJob({ schema, table, name, policy, limit, includeMetadata, priority = true, ignoreStartAfter = false, ignoreSingletons = null }) {
|
|
503
511
|
const singletonFetch = limit > 1 && (policy === QUEUE_POLICIES.singleton || policy === QUEUE_POLICIES.stately);
|
|
504
512
|
const cte = singletonFetch ? 'grouped' : 'next';
|
|
505
|
-
|
|
513
|
+
const hasIgnoreSingletons = ignoreSingletons != null && ignoreSingletons.length > 0;
|
|
514
|
+
return {
|
|
515
|
+
text: `
|
|
506
516
|
WITH next as (
|
|
507
517
|
SELECT id ${singletonFetch ? ', singleton_key' : ''}
|
|
508
518
|
FROM ${schema}.${table}
|
|
509
519
|
WHERE name = '${name}'
|
|
510
520
|
AND state < '${JOB_STATES.active}'
|
|
511
521
|
${ignoreStartAfter ? '' : 'AND start_after < now()'}
|
|
512
|
-
${
|
|
522
|
+
${hasIgnoreSingletons ? 'AND singleton_key <> ALL($1::text[])' : ''}
|
|
513
523
|
ORDER BY ${priority ? 'priority desc, ' : ''}created_on, id
|
|
514
524
|
LIMIT ${limit}
|
|
515
525
|
FOR UPDATE SKIP LOCKED
|
|
@@ -522,8 +532,10 @@ function fetchNextJob({ schema, table, name, policy, limit, includeMetadata, pri
|
|
|
522
532
|
FROM ${cte}
|
|
523
533
|
WHERE name = '${name}' AND j.id = ${cte}.id
|
|
524
534
|
${singletonFetch ? ` AND ${cte}.row_number = 1` : ''}
|
|
525
|
-
RETURNING j.${includeMetadata ? JOB_COLUMNS_ALL : JOB_COLUMNS_MIN}
|
|
526
|
-
|
|
535
|
+
RETURNING j.${includeMetadata ? JOB_COLUMNS_ALL : JOB_COLUMNS_MIN}
|
|
536
|
+
`,
|
|
537
|
+
values: hasIgnoreSingletons ? [ignoreSingletons] : []
|
|
538
|
+
};
|
|
527
539
|
}
|
|
528
540
|
function completeJobs(schema, table) {
|
|
529
541
|
return `
|
|
@@ -645,7 +657,7 @@ function failJobsById(schema, table) {
|
|
|
645
657
|
function failJobsByTimeout(schema, table, queues) {
|
|
646
658
|
const where = `state = '${JOB_STATES.active}'
|
|
647
659
|
AND (started_on + expire_seconds * interval '1s') < now()
|
|
648
|
-
AND name
|
|
660
|
+
AND name = ANY(${serializeArrayParam(queues)})`;
|
|
649
661
|
const output = '\'{ "value": { "message": "job timed out" } }\'::jsonb';
|
|
650
662
|
return locked(schema, failJobs(schema, table, where, output), table + 'failJobsByTimeout');
|
|
651
663
|
}
|
|
@@ -798,13 +810,13 @@ function failJobs(schema, table, where, output) {
|
|
|
798
810
|
function deletion(schema, table, queues) {
|
|
799
811
|
const sql = `
|
|
800
812
|
DELETE FROM ${schema}.${table}
|
|
801
|
-
WHERE name
|
|
813
|
+
WHERE name = ANY(${serializeArrayParam(queues)})
|
|
802
814
|
AND
|
|
803
815
|
(
|
|
804
816
|
completed_on + deletion_seconds * interval '1s' < now()
|
|
805
817
|
OR
|
|
806
818
|
(state < '${JOB_STATES.active}' AND keep_until < now())
|
|
807
|
-
)
|
|
819
|
+
)
|
|
808
820
|
`;
|
|
809
821
|
return locked(schema, sql, table + 'deletion');
|
|
810
822
|
}
|
|
@@ -823,22 +835,28 @@ function retryJobs(schema, table) {
|
|
|
823
835
|
`;
|
|
824
836
|
}
|
|
825
837
|
function getQueueStats(schema, table, queues) {
|
|
826
|
-
return
|
|
838
|
+
return {
|
|
839
|
+
text: `
|
|
827
840
|
SELECT
|
|
828
|
-
name,
|
|
841
|
+
name,
|
|
829
842
|
(count(*) FILTER (WHERE start_after > now()))::int as "deferredCount",
|
|
830
843
|
(count(*) FILTER (WHERE state < '${JOB_STATES.active}'))::int as "queuedCount",
|
|
831
844
|
(count(*) FILTER (WHERE state = '${JOB_STATES.active}'))::int as "activeCount",
|
|
832
845
|
count(*)::int as "totalCount",
|
|
833
846
|
array_agg(singleton_key) FILTER (WHERE policy IN ('${QUEUE_POLICIES.singleton}','${QUEUE_POLICIES.stately}') AND state = '${JOB_STATES.active}') as "singletonsActive"
|
|
834
847
|
FROM ${schema}.${table}
|
|
835
|
-
WHERE name
|
|
848
|
+
WHERE name = ANY($1::text[])
|
|
836
849
|
GROUP BY 1
|
|
837
|
-
|
|
850
|
+
`,
|
|
851
|
+
values: [queues]
|
|
852
|
+
};
|
|
838
853
|
}
|
|
839
854
|
function cacheQueueStats(schema, table, queues) {
|
|
855
|
+
const statsQuery = getQueueStats(schema, table, queues);
|
|
856
|
+
// Serialize the $1 parameter for use in locked() multi-statement query
|
|
857
|
+
const statsText = statsQuery.text.replace('$1::text[]', serializeArrayParam(queues));
|
|
840
858
|
const sql = `
|
|
841
|
-
WITH stats AS (${
|
|
859
|
+
WITH stats AS (${statsText})
|
|
842
860
|
UPDATE ${schema}.queue SET
|
|
843
861
|
deferred_count = "deferredCount",
|
|
844
862
|
queued_count = "queuedCount",
|
|
@@ -854,16 +872,19 @@ function cacheQueueStats(schema, table, queues) {
|
|
|
854
872
|
`;
|
|
855
873
|
return locked(schema, sql, 'queue-stats');
|
|
856
874
|
}
|
|
875
|
+
// Serialize a string array for embedding directly in SQL as PostgreSQL array literal
|
|
876
|
+
function serializeArrayParam(values) {
|
|
877
|
+
const escaped = values.map(v => `'${v.replace(SINGLE_QUOTE_REGEX, "''")}'`);
|
|
878
|
+
return `ARRAY[${escaped.join(',')}]::text[]`;
|
|
879
|
+
}
|
|
857
880
|
function locked(schema, query, key) {
|
|
858
|
-
|
|
859
|
-
query = query.join(';\n');
|
|
860
|
-
}
|
|
881
|
+
const sql = Array.isArray(query) ? query.join(';\n') : query;
|
|
861
882
|
return `
|
|
862
883
|
BEGIN;
|
|
863
884
|
SET LOCAL lock_timeout = 30000;
|
|
864
885
|
SET LOCAL idle_in_transaction_session_timeout = 30000;
|
|
865
886
|
${advisoryLock(schema, key)};
|
|
866
|
-
${
|
|
887
|
+
${sql};
|
|
867
888
|
COMMIT;
|
|
868
889
|
`;
|
|
869
890
|
}
|
|
@@ -879,7 +900,4 @@ function assertMigration(schema, version) {
|
|
|
879
900
|
function getJobById(schema, table) {
|
|
880
901
|
return `SELECT ${JOB_COLUMNS_ALL} FROM ${schema}.${table} WHERE name = $1 AND id = $2`;
|
|
881
902
|
}
|
|
882
|
-
function getQueueInClause(queues) {
|
|
883
|
-
return queues.map(i => `'${i}'`).join(',');
|
|
884
|
-
}
|
|
885
903
|
export { create, insertVersion, getVersion, setVersion, versionTableExists, fetchNextJob, completeJobs, cancelJobs, resumeJobs, retryJobs, deleteJobsById, deleteAllJobs, deleteQueuedJobs, deleteStoredJobs, truncateTable, failJobsById, failJobsByTimeout, insertJobs, getTime, getSchedules, getSchedulesByQueue, schedule, unschedule, subscribe, unsubscribe, getQueuesForEvent, deletion, cacheQueueStats, updateQueue, createQueue, deleteQueue, getQueues, getQueueStats, trySetQueueMonitorTime, trySetQueueDeletionTime, trySetCronTime, locked, assertMigration, getJobById, QUEUE_POLICIES, JOB_STATES, MIGRATE_RACE_MESSAGE, CREATE_RACE_MESSAGE, DEFAULT_SCHEMA, };
|