From 88168a009bbc98383c6b1cc8964691fa9c65d503 Mon Sep 17 00:00:00 2001 From: roggervalf Date: Sun, 8 Dec 2024 08:23:51 -0600 Subject: [PATCH] feat(scheduler): expose template data in getJobSchedulers --- src/classes/job-scheduler.ts | 40 ++++++++++++------------------ src/classes/queue.ts | 2 +- src/classes/scripts.ts | 14 +++++++++++ src/commands/getJobScheduler-1.lua | 19 ++++++++++++++ src/commands/updateJobOption-1.lua | 26 ------------------- tests/test_job_scheduler.ts | 6 ++++- tests/test_metrics.ts | 2 +- 7 files changed, 56 insertions(+), 53 deletions(-) create mode 100644 src/commands/getJobScheduler-1.lua delete mode 100644 src/commands/updateJobOption-1.lua diff --git a/src/classes/job-scheduler.ts b/src/classes/job-scheduler.ts index 85badf6fd3..bd47466ce5 100644 --- a/src/classes/job-scheduler.ts +++ b/src/classes/job-scheduler.ts @@ -11,7 +11,7 @@ import { Job } from './job'; import { QueueBase } from './queue-base'; import { RedisConnection } from './redis-connection'; import { SpanKind, TelemetryAttributes } from '../enums'; -import { optsAsJSON, optsFromJSON } from '../utils'; +import { array2obj, optsAsJSON, optsFromJSON } from '../utils'; export class JobScheduler extends QueueBase { private repeatStrategy: RepeatStrategy; @@ -209,6 +209,14 @@ export class JobScheduler extends QueueBase { ): Promise> { const jobData = await client.hgetall(this.toKey('repeat:' + key)); + return this.transformSchedulerData(key, jobData, next); + } + + private async transformSchedulerData( + key: string, + jobData: any, + next?: number, + ): Promise> { if (jobData) { return { key, @@ -244,30 +252,14 @@ export class JobScheduler extends QueueBase { }; } - async getJobScheduler(id: string): Promise> { - const client = await this.client; - const schedulerAttributes = await client.hgetall( - this.toKey('repeat:' + id), - ); + async getScheduler(id: string): Promise> { + const [rawJobData, next] = await this.scripts.getJobScheduler(id); - if (schedulerAttributes) { - return { - key: id, - name: schedulerAttributes.name, - endDate: parseInt(schedulerAttributes.endDate) || null, - tz: schedulerAttributes.tz || null, - pattern: schedulerAttributes.pattern || null, - every: schedulerAttributes.every || null, - ...(schedulerAttributes.data || schedulerAttributes.opts - ? { - template: this.getTemplateFromJSON( - schedulerAttributes.data, - schedulerAttributes.opts, - ), - } - : {}), - }; - } + return this.transformSchedulerData( + id, + rawJobData ? array2obj(rawJobData) : null, + next ? parseInt(next) : null, + ); } private getTemplateFromJSON( diff --git a/src/classes/queue.ts b/src/classes/queue.ts index 5c61c88e2c..1525d13254 100644 --- a/src/classes/queue.ts +++ b/src/classes/queue.ts @@ -573,7 +573,7 @@ export class Queue< * @param id - identifier of scheduler. */ async getJobScheduler(id: string): Promise> { - return (await this.jobScheduler).getJobScheduler(id); + return (await this.jobScheduler).getScheduler(id); } /** diff --git a/src/classes/scripts.ts b/src/classes/scripts.ts index 0897d905a9..dc487b42d1 100644 --- a/src/classes/scripts.ts +++ b/src/classes/scripts.ts @@ -1088,6 +1088,20 @@ export class Scripts { ]); } + getJobSchedulerArgs(id: string): string[] { + const keys: string[] = [this.queue.keys.repeat]; + + return keys.concat([id]); + } + + async getJobScheduler(id: string): Promise<[any, string | null]> { + const client = await this.queue.client; + + const args = this.getJobSchedulerArgs(id); + + return this.execCommand(client, 'getJobScheduler', args); + } + retryJobArgs( jobId: string, lifo: boolean, diff --git a/src/commands/getJobScheduler-1.lua b/src/commands/getJobScheduler-1.lua new file mode 100644 index 0000000000..324bdb58eb --- /dev/null +++ b/src/commands/getJobScheduler-1.lua @@ -0,0 +1,19 @@ +--[[ + Get job scheduler record. + + Input: + KEYS[1] 'repeat' key + + ARGV[1] id +]] + +local rcall = redis.call +local jobSchedulerKey = KEYS[1] .. ":" .. ARGV[1] + +local score = rcall("ZSCORE", KEYS[1], ARGV[1]) + +if score then + return {rcall("HGETALL", jobSchedulerKey), score} -- get job data +end + +return {nil, nil} diff --git a/src/commands/updateJobOption-1.lua b/src/commands/updateJobOption-1.lua deleted file mode 100644 index 03949faf29..0000000000 --- a/src/commands/updateJobOption-1.lua +++ /dev/null @@ -1,26 +0,0 @@ ---[[ - Update a job option - - Input: - KEYS[1] Job id key - - ARGV[1] field - ARGV[2] value - - Output: - 0 - OK - -1 - Missing job. -]] -local rcall = redis.call - -if rcall("EXISTS", KEYS[1]) == 1 then -- // Make sure job exists - - local opts = rcall("HGET", KEYS[1], "opts") - local jsonOpts = cjson.decode(opts) - jsonOpts[ARGV[1]] = ARGV[2] - - rcall("HSET", KEYS[1], "opts", cjson.encode(jsonOpts)) - return 0 -else - return -1 -end diff --git a/tests/test_job_scheduler.ts b/tests/test_job_scheduler.ts index ffd6eee0d8..a44b17549a 100644 --- a/tests/test_job_scheduler.ts +++ b/tests/test_job_scheduler.ts @@ -360,6 +360,7 @@ describe('Job Scheduler', function () { tz: null, pattern: '*/2 * * * * *', every: null, + next: 1486481042000, template: { data: { foo: 'bar', @@ -698,6 +699,7 @@ describe('Job Scheduler', function () { key: 'rrule', name: 'rrule', endDate: null, + next: 1486481042000, tz: null, pattern: 'RRULE:FREQ=SECONDLY;INTERVAL=2;WKST=MO', every: null, @@ -1424,6 +1426,8 @@ describe('Job Scheduler', function () { describe('when repeatable job fails', function () { it('should continue repeating', async function () { + const date = new Date('2024-12-08 9:24:00'); + this.clock.setSystemTime(date); const repeatOpts = { pattern: '0 * 1 * *', }; @@ -1475,7 +1479,7 @@ describe('Job Scheduler', function () { tz: null, pattern: '0 * 1 * *', every: null, - next: 25200000, + next: 1735714800000, template: { data: { foo: 'bar', diff --git a/tests/test_metrics.ts b/tests/test_metrics.ts index 6433afc8b2..f59d4e44d7 100644 --- a/tests/test_metrics.ts +++ b/tests/test_metrics.ts @@ -28,7 +28,7 @@ describe('metrics', function () { }); beforeEach(function () { - this.clock = sinon.useFakeTimers(); + this.clock = sinon.useFakeTimers({ shouldClearNativeTimers: true }); }); beforeEach(async function () {