From 881b6eb5d752122896cc107cfb84e280451f2b3f Mon Sep 17 00:00:00 2001 From: Aras Abbasi Date: Wed, 21 Oct 2020 11:28:39 +0200 Subject: [PATCH 1/4] add more typings --- src/Job.ts | 10 ++++---- src/JobDbRepository.ts | 48 ++++++++++++++++++++++---------------- src/JobProcessingQueue.ts | 2 +- src/JobProcessor.ts | 8 +++---- src/index.ts | 16 ++++++------- src/types/AgendaStatus.ts | 2 +- src/types/DbOptions.ts | 4 ++-- src/types/JobDefinition.ts | 9 +++---- src/types/JobParameters.ts | 5 ++-- src/utils/nextRunAt.ts | 5 ++-- src/utils/priority.ts | 15 ++++++------ test/retry.test.ts | 4 ++-- 12 files changed, 65 insertions(+), 63 deletions(-) diff --git a/src/Job.ts b/src/Job.ts index 207715c..9c16d10 100644 --- a/src/Job.ts +++ b/src/Job.ts @@ -1,10 +1,10 @@ import * as date from 'date.js'; import * as debug from 'debug'; -import { JobPriority, parsePriority } from './utils/priority'; import type { Agenda } from './index'; -import { computeFromInterval, computeFromRepeatAt } from './utils/nextRunAt'; -import { IJobParameters } from './types/JobParameters'; +import type { IJobParameters } from './types/JobParameters'; import type { DefinitionProcessor } from './types/JobDefinition'; +import { JobPriority, parsePriority } from './utils/priority'; +import { computeFromInterval, computeFromRepeatAt } from './utils/nextRunAt'; const log = debug('agenda:job'); @@ -56,7 +56,7 @@ export class Job { }; } - toJson(): Partial { + toJson(): IJobParameters { const attrs = this.attrs || {}; const result = {}; @@ -75,7 +75,7 @@ export class Job { }); // console.log('toJson', this.attrs, result); - return result; + return result as IJobParameters; } repeatEvery( diff --git a/src/JobDbRepository.ts b/src/JobDbRepository.ts index aabbc9b..51b43ce 100644 --- a/src/JobDbRepository.ts +++ b/src/JobDbRepository.ts @@ -7,13 +7,14 @@ import { MongoClientOptions, UpdateQuery, ObjectId, - SortOptionObject + SortOptionObject, + FindOneAndUpdateOption } from 'mongodb'; import type { Job } from './Job'; -import { hasMongoProtocol } from './utils/hasMongoProtocol'; import type { Agenda } from './index'; -import { IDatabaseOptions, IDbConfig, IMongoOptions } from './types/DbOptions'; -import { IJobParameters } from './types/JobParameters'; +import type { IDatabaseOptions, IDbConfig, IMongoOptions } from './types/DbOptions'; +import type { IJobParameters } from './types/JobParameters'; +import { hasMongoProtocol } from './utils/hasMongoProtocol'; const log = debug('agenda:db'); @@ -81,7 +82,7 @@ export class JobDbRepository { async lockJob(job: Job): Promise { // Query to run against collection to see if we need to lock it - const criteria = { + const criteria: FilterQuery & { lockedAt?: Date | null }> = { _id: job.attrs._id, name: job.attrs.name, lockedAt: null, @@ -90,11 +91,16 @@ export class JobDbRepository { }; // Update / options for the MongoDB query - const update = { $set: { lockedAt: new Date() } }; - const options = { returnOriginal: false }; + const update: UpdateQuery = { $set: { lockedAt: new Date() } }; + const options: FindOneAndUpdateOption = { returnOriginal: false }; // Lock the job in MongoDB! - const resp = await this.collection.findOneAndUpdate(criteria, update, options); + const resp = await this.collection.findOneAndUpdate( + criteria as FilterQuery, + update, + options + ); + return resp?.value; } @@ -104,11 +110,13 @@ export class JobDbRepository { lockDeadline: Date, now: Date = new Date() ): Promise { - // /** - // * Query used to find job to run - // * @type {{$and: [*]}} - // */ - const JOB_PROCESS_WHERE_QUERY = { + /** + * Query used to find job to run + * @type {{$and: [*]}} + */ + const JOB_PROCESS_WHERE_QUERY: FilterQuery< + Omit & { lockedAt?: Date | null } + > = { $and: [ { name: jobName, @@ -132,13 +140,16 @@ export class JobDbRepository { * Query used to set a job as locked * @type {{$set: {lockedAt: Date}}} */ - const JOB_PROCESS_SET_QUERY = { $set: { lockedAt: now } }; + const JOB_PROCESS_SET_QUERY: UpdateQuery = { $set: { lockedAt: now } }; /** * Query used to affect what gets returned * @type {{returnOriginal: boolean, sort: object}} */ - const JOB_RETURN_QUERY = { returnOriginal: false, sort: this.connectOptions.sort }; + const JOB_RETURN_QUERY: FindOneAndUpdateOption = { + returnOriginal: false, + sort: this.connectOptions.sort + }; // Find ONE and ONLY ONE job and set the 'lockedAt' time so that job begins to be processed const result = await this.collection.findOneAndUpdate( @@ -208,7 +219,7 @@ export class JobDbRepository { private processDbResult( job: Job, - res: IJobParameters + res?: IJobParameters ): Job { log( 'processDbResult() called with success, checking whether to process job immediately or not' @@ -243,7 +254,6 @@ export class JobDbRepository { // Grab information needed to save job but that we don't want to persist in MongoDB const id = job.attrs._id; - // const { unique, uniqueOpts } = job.attrs; // Store job as JSON and remove props we don't want to store from object // _id, unique, uniqueOpts @@ -309,7 +319,7 @@ export class JobDbRepository { update, { upsert: true, - returnOriginal: false // same as new: true -> returns the final document + returnOriginal: false } ); log( @@ -330,8 +340,6 @@ export class JobDbRepository { update = { $setOnInsert: props }; } - // console.log('update', query, update, uniqueOpts); - // Use the 'unique' query object to find an existing job or create a new one log('calling findOneAndUpdate() with unique object as query: \n%O', query); const result = await this.collection.findOneAndUpdate(query, update, { diff --git a/src/JobProcessingQueue.ts b/src/JobProcessingQueue.ts index bc94f39..ae9f6e9 100644 --- a/src/JobProcessingQueue.ts +++ b/src/JobProcessingQueue.ts @@ -1,6 +1,6 @@ // eslint-disable-next-line prettier/prettier import type { Job } from './Job'; -import { IJobParameters } from './types/JobParameters'; +import type { IJobParameters } from './types/JobParameters'; import type { Agenda } from './index'; /** * @class diff --git a/src/JobProcessor.ts b/src/JobProcessor.ts index 599d45e..90195e6 100644 --- a/src/JobProcessor.ts +++ b/src/JobProcessor.ts @@ -1,10 +1,10 @@ import * as debug from 'debug'; -import { Job } from './Job'; -import { IAgendaJobStatus, IAgendaStatus } from './types/AgendaStatus'; -import { IJobDefinition } from './types/JobDefinition'; -import { JobProcessingQueue } from './JobProcessingQueue'; +import type { IAgendaJobStatus, IAgendaStatus } from './types/AgendaStatus'; +import type { IJobDefinition } from './types/JobDefinition'; import type { Agenda } from './index'; import type { IJobParameters } from './types/JobParameters'; +import { Job } from './Job'; +import { JobProcessingQueue } from './JobProcessingQueue'; const log = debug('agenda:jobProcessor'); diff --git a/src/index.ts b/src/index.ts index 0c68291..f971b3b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,17 +2,17 @@ import { EventEmitter } from 'events'; import * as debug from 'debug'; import * as humanInterval from 'human-interval'; -import { Db, FilterQuery, MongoClientOptions, SortOptionObject } from 'mongodb'; -import { Job } from './Job'; -import { JobProcessor } from './JobProcessor'; +import type { Db, FilterQuery, MongoClientOptions, SortOptionObject } from 'mongodb'; import type { IJobDefinition } from './types/JobDefinition'; -import { IAgendaConfig } from './types/AgendaConfig'; +import type { IAgendaConfig } from './types/AgendaConfig'; +import type { IDatabaseOptions, IDbConfig, IMongoOptions } from './types/DbOptions'; +import type { IAgendaStatus } from './types/AgendaStatus'; +import type { IJobParameters } from './types/JobParameters'; +import { Job } from './Job'; import { JobDbRepository } from './JobDbRepository'; -import { IDatabaseOptions, IDbConfig, IMongoOptions } from './types/DbOptions'; -import { filterUndefined } from './utils/filterUndefined'; +import { JobProcessor } from './JobProcessor'; import { JobPriority, parsePriority } from './utils/priority'; -import { IAgendaStatus } from './types/AgendaStatus'; -import { IJobParameters } from './types/JobParameters'; +import { filterUndefined } from './utils/filterUndefined'; const log = debug('agenda'); diff --git a/src/types/AgendaStatus.ts b/src/types/AgendaStatus.ts index 0116302..ebddb05 100644 --- a/src/types/AgendaStatus.ts +++ b/src/types/AgendaStatus.ts @@ -1,4 +1,4 @@ -import { Job } from '../Job'; +import type { Job } from '../Job'; export interface IAgendaJobStatus { [name: string]: { running: number; locked: number }; diff --git a/src/types/DbOptions.ts b/src/types/DbOptions.ts index c3cefe3..3030978 100644 --- a/src/types/DbOptions.ts +++ b/src/types/DbOptions.ts @@ -1,5 +1,5 @@ -import { Db, MongoClientOptions, SortOptionObject } from 'mongodb'; -import { IJobParameters } from './JobParameters'; +import type { Db, MongoClientOptions, SortOptionObject } from 'mongodb'; +import type { IJobParameters } from './JobParameters'; export interface IDatabaseOptions { db: { diff --git a/src/types/JobDefinition.ts b/src/types/JobDefinition.ts index 4c5d61b..bea5ffb 100644 --- a/src/types/JobDefinition.ts +++ b/src/types/JobDefinition.ts @@ -1,4 +1,4 @@ -import { Job } from '../Job'; +import type { Job } from '../Job'; export interface IJobDefinition { /** max number of locked jobs of this kind */ @@ -7,13 +7,10 @@ export interface IJobDefinition { lockLifetime: number; /** Higher priority jobs will run first. */ priority?: number; - /** how many jobs of this kind can run in parallel/simultanously */ + /** how many jobs of this kind can run in parallel/simultanously per Agenda instance */ concurrency?: number; - // running: number; - // locked: number; - - fn: DefinitionProcessor void)>; + fn: DefinitionProcessor void)>; } export type DefinitionProcessor = ( diff --git a/src/types/JobParameters.ts b/src/types/JobParameters.ts index 9fa8e17..04273d4 100644 --- a/src/types/JobParameters.ts +++ b/src/types/JobParameters.ts @@ -6,13 +6,12 @@ export interface IJobParameters { name: string; priority: number; - nextRunAt: Date | null; + nextRunAt?: Date | null; /** - * // once: the job is just queued in the database --> this does not really exists, it's just fallback * normal: job is queued and will be processed (regular case when the user adds a new job) * single: job with this name is only queued once, if there is an exisitn gentry in the database, the job is just updated, but not newly inserted (this is used for .every()) */ - type: /* 'once' | */ 'normal' | 'single'; + type: 'normal' | 'single'; lockedAt?: Date; lastFinishedAt?: Date; diff --git a/src/utils/nextRunAt.ts b/src/utils/nextRunAt.ts index ba311b3..79b66ab 100644 --- a/src/utils/nextRunAt.ts +++ b/src/utils/nextRunAt.ts @@ -4,7 +4,7 @@ import * as moment from 'moment-timezone'; import * as humanInterval from 'human-interval'; import * as date from 'date.js'; import * as debug from 'debug'; -import { IJobParameters } from '../types/JobParameters'; +import type { IJobParameters } from '../types/JobParameters'; import { isValidDate } from './date'; const log = debug('agenda:nextRunAt'); @@ -15,7 +15,7 @@ const dateForTimezone = (timezoneDate: Date, timezone?: string): moment.Moment = momentDate.tz(timezone); } - return momentDate; // .utc(false).toDate(); + return momentDate; }; /** @@ -41,7 +41,6 @@ export const computeFromInterval = (attrs: IJobParameters): Date => { } result = nextDate; - // Either `xo` linter or Node.js 8 stumble on this line if it isn't just ignored } catch (error) { // eslint-disable-line no-unused-vars // Nope, humanInterval then! diff --git a/src/utils/priority.ts b/src/utils/priority.ts index 61fac28..eff4d08 100644 --- a/src/utils/priority.ts +++ b/src/utils/priority.ts @@ -1,11 +1,3 @@ -/** - * Internal method to turn priority into a number - * @name Job#priority - * @function - * @param {String|Number} priority string to parse into number - * @returns {Number} priority that was parsed - */ - export type JobPriority = number | keyof typeof priorityMap; const priorityMap = { @@ -16,6 +8,13 @@ const priorityMap = { highest: 20 }; +/** + * Internal method to turn priority into a number + * @name Job#priority + * @function + * @param {String|Number} priority string to parse into number + * @returns {Number} priority that was parsed + */ export function parsePriority(priority?: JobPriority): number { if (typeof priority === 'number') { return priority; diff --git a/test/retry.test.ts b/test/retry.test.ts index 372963f..682f269 100644 --- a/test/retry.test.ts +++ b/test/retry.test.ts @@ -16,7 +16,7 @@ const clearJobs = async (): Promise => { }; const jobType = 'do work'; -const jobProcessor = () => {}; +const jobProcessor = () => { }; describe('Retry', () => { beforeEach(async () => { @@ -79,5 +79,5 @@ describe('Retry', () => { await agenda.start(); await successPromise; - }); + }).timeout(100000); }); From 8f7424d35a6249a3abd4927739c992bbf866e3dc Mon Sep 17 00:00:00 2001 From: Aras Abbasi Date: Wed, 21 Oct 2020 14:23:18 +0200 Subject: [PATCH 2/4] refactor nextRunAt and processEvery --- package-lock.json | 12 +++++ package.json | 24 +++++---- src/index.ts | 7 ++- src/utils/{date.ts => isValidDate.ts} | 4 +- src/utils/nextRunAt.ts | 73 ++++++++++++++++----------- src/utils/processEvery.ts | 16 ++++++ 6 files changed, 89 insertions(+), 47 deletions(-) rename src/utils/{date.ts => isValidDate.ts} (50%) create mode 100644 src/utils/processEvery.ts diff --git a/package-lock.json b/package-lock.json index 430479d..d527bbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -278,6 +278,18 @@ "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", "dev": true }, + "@types/debug": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.5.tgz", + "integrity": "sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ==", + "dev": true + }, + "@types/human-interval": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/human-interval/-/human-interval-1.0.0.tgz", + "integrity": "sha512-ud7H6R7y58RpOFcJPhmuCacUAaE5Tpkhhm1gwx3vaaAiVEvqalvG/yaG6K0+yPaSEorkI/HGKp0/H3xirxJ4Tg==", + "dev": true + }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", diff --git a/package.json b/package.json index 4177887..35e5985 100644 --- a/package.json +++ b/package.json @@ -57,27 +57,29 @@ "mongodb": "~3.6.2" }, "devDependencies": { - "standard-version": "^9.0.0", + "@hokify/eslint-config": "^0.5.10", "@types/chai": "^4.2.14", - "@types/node": "^14.14.0", + "@types/debug": "^4.1.5", + "@types/human-interval": "^1.0.0", "@types/mocha": "^8.0.3", - "@types/sinon": "^9.0.8", - "ts-node": "^9.0.0", - "typescript": "^4.0.3", - "mongodb-memory-server": "^6.9.2", - "@hokify/eslint-config": "^0.5.10", - "eslint": "7.11.0", - "prettier": "^2.1.2", "@types/mongodb": "^3.5.29", + "@types/node": "^14.14.0", + "@types/sinon": "^9.0.8", "blanket": "1.2.3", + "chai": "^4.2.0", "coveralls": "3.1.0", "delay": "4.4.0", - "chai": "^4.2.0", + "eslint": "7.11.0", "jsdoc": "3.6.6", "jsdoc-template": "https://github.com/braintree/jsdoc-template", "mocha": "8.2.0", "mocha-lcov-reporter": "1.3.0", + "mongodb-memory-server": "^6.9.2", + "prettier": "^2.1.2", "q": "1.5.1", - "sinon": "9.2.0" + "sinon": "9.2.0", + "standard-version": "^9.0.0", + "ts-node": "^9.0.0", + "typescript": "^4.0.3" } } diff --git a/src/index.ts b/src/index.ts index 0c68291..f0de99f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,6 @@ import { EventEmitter } from 'events'; import * as debug from 'debug'; -import * as humanInterval from 'human-interval'; import { Db, FilterQuery, MongoClientOptions, SortOptionObject } from 'mongodb'; import { Job } from './Job'; import { JobProcessor } from './JobProcessor'; @@ -13,6 +12,7 @@ import { filterUndefined } from './utils/filterUndefined'; import { JobPriority, parsePriority } from './utils/priority'; import { IAgendaStatus } from './types/AgendaStatus'; import { IJobParameters } from './types/JobParameters'; +import { calculateProcessEvery } from './utils/processEvery'; const log = debug('agenda'); @@ -90,8 +90,7 @@ export class Agenda extends EventEmitter { this.attrs = { name: config.name || '', - processEvery: - (config.processEvery && humanInterval(config.processEvery)) || humanInterval('5 seconds'), + processEvery: calculateProcessEvery(config.processEvery), defaultConcurrency: config.defaultConcurrency || 5, maxConcurrency: config.maxConcurrency || 20, defaultLockLimit: config.defaultLockLimit || 0, @@ -158,7 +157,7 @@ export class Agenda extends EventEmitter { processEvery(time: string | number): Agenda { log('Agenda.processEvery(%d)', time); - this.attrs.processEvery = humanInterval(time); + this.attrs.processEvery = calculateProcessEvery(time); return this; } diff --git a/src/utils/date.ts b/src/utils/isValidDate.ts similarity index 50% rename from src/utils/date.ts rename to src/utils/isValidDate.ts index 5d4f52b..1b8c005 100644 --- a/src/utils/date.ts +++ b/src/utils/isValidDate.ts @@ -1,6 +1,6 @@ -export function isValidDate(date: Date): boolean { +export function isValidDate(date: unknown): date is Date { // An invalid date object returns NaN for getTime() and NaN is the only // object not strictly equal to itself. // eslint-disable-next-line no-self-compare - return new Date(date).getTime() === new Date(date).getTime(); + return date !== null && new Date(date as string).getTime() === new Date(date as string).getTime(); } diff --git a/src/utils/nextRunAt.ts b/src/utils/nextRunAt.ts index ba311b3..4248be1 100644 --- a/src/utils/nextRunAt.ts +++ b/src/utils/nextRunAt.ts @@ -1,11 +1,10 @@ import { CronTime } from 'cron'; import * as moment from 'moment-timezone'; -// what's the difference to regular moment package? import * as humanInterval from 'human-interval'; import * as date from 'date.js'; import * as debug from 'debug'; -import { IJobParameters } from '../types/JobParameters'; -import { isValidDate } from './date'; +import type { IJobParameters } from '../types/JobParameters'; +import { isValidDate } from './isValidDate'; const log = debug('agenda:nextRunAt'); @@ -15,9 +14,15 @@ const dateForTimezone = (timezoneDate: Date, timezone?: string): moment.Moment = momentDate.tz(timezone); } - return momentDate; // .utc(false).toDate(); + return momentDate; }; +export function isValidHumanInterval(value: unknown): value is string { + const transformedValue = humanInterval(value as string); + // eslint-disable-next-line no-restricted-globals + return typeof transformedValue === 'number' && isNaN(transformedValue) === false; +} + /** * Internal method that computes the interval * @returns {undefined} @@ -26,33 +31,38 @@ export const computeFromInterval = (attrs: IJobParameters): Date => { const previousNextRunAt = attrs.nextRunAt || new Date(); log('[%s:%s] computing next run via interval [%s]', attrs.name, attrs._id, attrs.repeatInterval); const lastRun = dateForTimezone(attrs.lastRunAt || new Date(), attrs.repeatTimezone); - let result: Date; - try { - const cronTime = new CronTime(attrs.repeatInterval); - let nextDate = cronTime._getNextDateFrom(lastRun); - if ( - nextDate.valueOf() === lastRun.valueOf() || - nextDate.valueOf() <= previousNextRunAt.valueOf() - ) { - // Handle cronTime giving back the same date for the next run time - nextDate = cronTime._getNextDateFrom( - dateForTimezone(new Date(lastRun.valueOf() + 1000), attrs.repeatTimezone) - ); - } + let nextRunAt: Date | null = null; - result = nextDate; - // Either `xo` linter or Node.js 8 stumble on this line if it isn't just ignored - } catch (error) { - // eslint-disable-line no-unused-vars - // Nope, humanInterval then! - if (!attrs.lastRunAt && humanInterval(attrs.repeatInterval)) { - result = new Date(lastRun.valueOf()); + if (typeof attrs.repeatInterval === 'string') { + try { + const cronTime = new CronTime(attrs.repeatInterval); + let nextDate: Date = cronTime._getNextDateFrom(lastRun); + if ( + nextDate.valueOf() === lastRun.valueOf() || + nextDate.valueOf() <= previousNextRunAt.valueOf() + ) { + // Handle cronTime giving back the same date for the next run time + nextDate = cronTime._getNextDateFrom( + dateForTimezone(new Date(lastRun.valueOf() + 1000), attrs.repeatTimezone) + ); + } + + nextRunAt = nextDate; + + // eslint-disable-next-line no-empty + } catch (error) {} + } + + if (isValidHumanInterval(attrs.repeatInterval)) { + if (!attrs.lastRunAt) { + nextRunAt = new Date(lastRun.valueOf()); } else { - result = new Date(lastRun.valueOf() + humanInterval(attrs.repeatInterval)); + const intervalValue = humanInterval(attrs.repeatInterval) as number; + nextRunAt = new Date(lastRun.valueOf() + intervalValue); } } - if (!isValidDate(result)) { + if (!isValidDate(nextRunAt)) { log( '[%s:%s] failed to calculate nextRunAt due to invalid repeat interval', attrs.name, @@ -61,7 +71,7 @@ export const computeFromInterval = (attrs: IJobParameters): Date => { throw new Error('failed to calculate nextRunAt due to invalid repeat interval'); } - return result; + return nextRunAt; }; /** @@ -74,14 +84,17 @@ export function computeFromRepeatAt(attrs: IJobParameters): Date { // If you do not specify offset date for below test it will fail for ms const offset = Date.now(); + if (offset === date(attrs.repeatAt, offset).valueOf()) { log('[%s:%s] failed to calculate repeatAt due to invalid format', attrs.name, attrs._id); // this.attrs.nextRunAt = undefined; // this.fail('failed to calculate repeatAt time due to invalid format'); throw new Error('failed to calculate repeatAt time due to invalid format'); - } else if (nextDate.valueOf() === lastRun.valueOf()) { + } + + if (nextDate.valueOf() === lastRun.valueOf()) { return date('tomorrow at ', attrs.repeatAt); - } else { - return date(attrs.repeatAt); } + + return date(attrs.repeatAt); } diff --git a/src/utils/processEvery.ts b/src/utils/processEvery.ts new file mode 100644 index 0000000..592f556 --- /dev/null +++ b/src/utils/processEvery.ts @@ -0,0 +1,16 @@ +import * as humanInterval from 'human-interval'; +import { isValidHumanInterval } from './nextRunAt'; + +export function calculateProcessEvery(input?: number | string): number { + let result = 5000; + + if (typeof input === 'number') { + result = input; + } + + if (isValidHumanInterval(input)) { + result = humanInterval(input) as number; + } + + return result; +} From 645229b6a777cb930f4231feb84ffb4e3e6dcd78 Mon Sep 17 00:00:00 2001 From: Uzlopak Date: Wed, 21 Oct 2020 22:19:36 +0200 Subject: [PATCH 3/4] reduce complexity of calculateProcessEvery --- src/utils/processEvery.ts | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/src/utils/processEvery.ts b/src/utils/processEvery.ts index 592f556..3ed4240 100644 --- a/src/utils/processEvery.ts +++ b/src/utils/processEvery.ts @@ -1,16 +1,6 @@ import * as humanInterval from 'human-interval'; -import { isValidHumanInterval } from './nextRunAt'; -export function calculateProcessEvery(input?: number | string): number { - let result = 5000; - - if (typeof input === 'number') { - result = input; - } - - if (isValidHumanInterval(input)) { - result = humanInterval(input) as number; - } - - return result; +export function calculateProcessEvery(input: number | string = 5000): number { + if (typeof input === 'number') return input; + return (humanInterval(input) as number) || 5000; } From f47205a109bdc7b2bc5ff7c477f6474e1be6b56d Mon Sep 17 00:00:00 2001 From: Aras Abbasi Date: Thu, 22 Oct 2020 10:00:55 +0200 Subject: [PATCH 4/4] minor changes in interfaces --- src/Job.ts | 1 - src/JobDbRepository.ts | 2 +- src/types/JobParameters.ts | 2 +- test/job.test.ts | 10 +++++----- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/Job.ts b/src/Job.ts index 9c16d10..9c7aa77 100644 --- a/src/Job.ts +++ b/src/Job.ts @@ -74,7 +74,6 @@ export class Job { } }); - // console.log('toJson', this.attrs, result); return result as IJobParameters; } diff --git a/src/JobDbRepository.ts b/src/JobDbRepository.ts index 51b43ce..2f3caff 100644 --- a/src/JobDbRepository.ts +++ b/src/JobDbRepository.ts @@ -294,7 +294,7 @@ export class JobDbRepository { if (props.nextRunAt && props.nextRunAt <= now) { log('job has a scheduled nextRunAt time, protecting that field from upsert'); protect.nextRunAt = props.nextRunAt; - delete props.nextRunAt; + delete (props as Partial).nextRunAt; } // If we have things to protect, set them in MongoDB using $setOnInsert diff --git a/src/types/JobParameters.ts b/src/types/JobParameters.ts index 04273d4..170cda5 100644 --- a/src/types/JobParameters.ts +++ b/src/types/JobParameters.ts @@ -6,7 +6,7 @@ export interface IJobParameters { name: string; priority: number; - nextRunAt?: Date | null; + nextRunAt: Date | null; /** * normal: job is queued and will be processed (regular case when the user adds a new job) * single: job with this name is only queued once, if there is an exisitn gentry in the database, the job is just updated, but not newly inserted (this is used for .every()) diff --git a/test/job.test.ts b/test/job.test.ts index dfd0b88..564661e 100644 --- a/test/job.test.ts +++ b/test/job.test.ts @@ -1105,23 +1105,23 @@ describe('Job', () => { }) ); - console.log('1'); + // console.log('1'); await Promise.all([ agenda.create('priority').schedule(now).save(), agenda.create('priority').schedule(now).priority('low').save(), agenda.create('priority').schedule(now).priority('high').save() ]); - console.log('2'); + // console.log('2'); await agenda.start(); - console.log('3'); + // console.log('3'); try { await Promise.race([ checkResultsPromise, new Promise((_, reject) => setTimeout(() => reject(`not processed`), 2000)) ]); - console.log('4'); + // console.log('4'); } catch (err) { - console.log('stats', JSON.stringify(await agenda.getRunningStats(), undefined, 3)); + // console.log('stats', JSON.stringify(await agenda.getRunningStats(), undefined, 3)); } });