Socket
Socket
Sign inDemoInstall

@tngtech/momo-scheduler

Package Overview
Dependencies
228
Maintainers
6
Versions
16
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.0.1 to 2.0.2

5

CHANGELOG.md

@@ -6,4 +6,7 @@ # Change Log

## v2.0.2 (2023-09-15)
- Fix: prevent a race condition when starting jobs ([#603](https://github.com/TNG/momo-scheduler/issues/603) and [#604](https://github.com/TNG/momo-scheduler/issues/604))
- Chore: add [mongodb](https://www.npmjs.com/package/mongodb) v6 support
## v2.0.1 (2023-06-12)
- Fix: fixed [CVE](https://github.com/advisories/GHSA-6w63-h3fj-q4vw) in [fast-xml-parser](https://www.npmjs.com/package/fast-xml-parser)

@@ -10,0 +13,0 @@

13

dist/repository/SchedulesRepository.js

@@ -9,2 +9,6 @@ "use strict";

exports.SCHEDULES_COLLECTION_NAME = 'schedules';
const mongoOptions = {
returnDocument: 'after',
includeResultMetadata: true, // ensures backwards compatibility with mongodb <6
};
class SchedulesRepository extends Repository_1.Repository {

@@ -40,6 +44,3 @@ constructor(mongoClient, deadScheduleThreshold, scheduleId, name, collectionPrefix) {

},
}, {
upsert: true,
returnDocument: 'after',
});
}, Object.assign(Object.assign({}, mongoOptions), { upsert: true }));
return result.value === null ? false : result.value.scheduleId === this.scheduleId;

@@ -84,3 +85,3 @@ }

if (maxRunning < 1) {
const schedule = yield this.collection.findOneAndUpdate({ name: this.name }, { $inc: { [`executions.${name}`]: 1 } }, { returnDocument: 'after' });
const schedule = yield this.collection.findOneAndUpdate({ name: this.name }, { $inc: { [`executions.${name}`]: 1 } }, mongoOptions);
return { added: schedule.value !== null, running: (_b = (_a = schedule.value) === null || _a === void 0 ? void 0 : _a.executions[name]) !== null && _b !== void 0 ? _b : 0 };

@@ -91,3 +92,3 @@ }

$or: [{ [`executions.${name}`]: { $lt: maxRunning } }, { [`executions.${name}`]: { $exists: false } }],
}, { $inc: { [`executions.${name}`]: 1 } }, { returnDocument: 'after' });
}, { $inc: { [`executions.${name}`]: 1 } }, mongoOptions);
return { added: schedule.value !== null, running: (_d = (_c = schedule.value) === null || _c === void 0 ? void 0 : _c.executions[name]) !== null && _d !== void 0 ? _d : maxRunning };

@@ -94,0 +95,0 @@ });

@@ -11,3 +11,3 @@ import { SchedulesRepository } from '../repository/SchedulesRepository';

private handle?;
private startedJobs;
private startJobsStatus;
constructor(scheduleId: string, scheduleName: string, schedulesRepository: SchedulesRepository, logger: Logger, interval: number, startAllJobs: () => Promise<void>);

@@ -14,0 +14,0 @@ start(): Promise<void>;

@@ -7,2 +7,8 @@ "use strict";

const MomoErrorType_1 = require("../logging/error/MomoErrorType");
var StartJobsStatus;
(function (StartJobsStatus) {
StartJobsStatus[StartJobsStatus["notStarted"] = 0] = "notStarted";
StartJobsStatus[StartJobsStatus["inProgress"] = 1] = "inProgress";
StartJobsStatus[StartJobsStatus["finished"] = 2] = "finished";
})(StartJobsStatus || (StartJobsStatus = {}));
class SchedulePing {

@@ -16,3 +22,3 @@ constructor(scheduleId, scheduleName, schedulesRepository, logger, interval, startAllJobs) {

this.startAllJobs = startAllJobs;
this.startedJobs = false;
this.startJobsStatus = StartJobsStatus.notStarted;
}

@@ -40,6 +46,8 @@ start() {

yield this.schedulesRepository.ping(this.scheduleId);
if (!this.startedJobs) {
this.logger.debug(`This schedule just turned active`);
if (this.startJobsStatus === StartJobsStatus.notStarted) {
this.startJobsStatus = StartJobsStatus.inProgress;
this.logger.debug('This schedule just turned active');
yield this.startAllJobs();
this.startedJobs = true;
this.startJobsStatus = StartJobsStatus.finished;
this.logger.debug('Finished starting scheduled jobs');
}

@@ -46,0 +54,0 @@ }

{
"name": "@tngtech/momo-scheduler",
"version": "2.0.1",
"version": "2.0.2",
"description": "momo is a scheduler that persists jobs in mongodb",

@@ -33,44 +33,44 @@ "main": "dist/index.js",

"dependencies": {
"cron": "2.3.1",
"cron-parser": "4.8.1",
"cron": "2.4.3",
"cron-parser": "4.9.0",
"human-interval": "2.0.1",
"lodash": "4.17.21",
"luxon": "3.3.0",
"luxon": "3.4.3",
"neverthrow": "6.0.0",
"typed-emitter": "2.1.0",
"uuid": "9.0.0"
"uuid": "9.0.1"
},
"peerDependencies": {
"mongodb": "4 || 5"
"mongodb": "4 || 5 || 6"
},
"devDependencies": {
"@sinonjs/fake-timers": "10.2.0",
"@sinonjs/fake-timers": "11.1.0",
"@types/cron": "2.0.1",
"@types/human-interval": "1.0.0",
"@types/jest": "29.5.1",
"@types/lodash": "4.14.195",
"@types/luxon": "3.3.0",
"@types/node": "16.18.34",
"@types/jest": "29.5.4",
"@types/lodash": "4.14.198",
"@types/luxon": "3.3.2",
"@types/node": "16.18.51",
"@types/pino": "7.0.4",
"@types/sinonjs__fake-timers": "8.1.2",
"@types/uuid": "9.0.1",
"@typescript-eslint/eslint-plugin": "5.59.7",
"@typescript-eslint/parser": "5.59.7",
"eslint": "8.42.0",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jest": "27.2.1",
"eslint-plugin-jsdoc": "46.2.6",
"eslint-plugin-markdown": "3.0.0",
"@types/uuid": "9.0.4",
"@typescript-eslint/eslint-plugin": "6.7.0",
"@typescript-eslint/parser": "6.7.0",
"eslint": "8.49.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-import": "2.28.1",
"eslint-plugin-jest": "27.2.3",
"eslint-plugin-jsdoc": "46.8.0",
"eslint-plugin-markdown": "3.0.1",
"eslint-plugin-prefer-arrow": "1.2.3",
"eslint-plugin-prettier": "4.2.1",
"jest": "29.5.0",
"mongodb-memory-server": "8.13.0",
"pino": "8.14.1",
"prettier": "2.8.8",
"ts-jest": "29.1.0",
"eslint-plugin-prettier": "5.0.0",
"jest": "29.7.0",
"mongodb-memory-server": "8.15.1",
"pino": "8.15.1",
"prettier": "3.0.3",
"ts-jest": "29.1.1",
"ts-mockito": "2.6.1",
"ts-node": "10.9.1",
"typescript": "5.1.3"
"typescript": "5.2.2"
}
}

@@ -21,3 +21,3 @@ import { MongoClient } from 'mongodb';

private readonly schedulesRepository: SchedulesRepository,
private readonly jobRepository: JobRepository
private readonly jobRepository: JobRepository,
) {}

@@ -29,3 +29,3 @@

scheduleId: string,
scheduleName: string
scheduleName: string,
): Promise<Connection> {

@@ -40,3 +40,3 @@ const mongoClient = new MongoClient(url);

scheduleName,
collectionsPrefix
collectionsPrefix,
);

@@ -43,0 +43,0 @@ await schedulesRepository.createIndex();

@@ -18,3 +18,3 @@ import { DateTime } from 'luxon';

private readonly jobRepository: JobRepository,
private readonly logger: Logger
private readonly logger: Logger,
) {}

@@ -63,3 +63,3 @@

jobEntity: JobEntity,
parameters?: JobParameters
parameters?: JobParameters,
): Promise<{ started: DateTime; result: JobResult }> {

@@ -66,0 +66,0 @@ this.logger.debug('run job', { name: jobEntity.name });

@@ -108,5 +108,5 @@ import humanInterval from 'human-interval';

Schedule extends ParsedIntervalSchedule | CronSchedule,
Type extends JobDefinition<Schedule>
Type extends JobDefinition<Schedule>,
>({ name, schedule, maxRunning, concurrency, parameters }: Type): JobDefinition<Schedule> {
return { name, schedule, maxRunning, concurrency, parameters };
}

@@ -20,5 +20,5 @@ import TypedEmitter from 'typed-emitter';

data?: MomoEventData,
error?: unknown
error?: unknown,
): void {
this.emit('error', { message, type, data, error });
}

@@ -8,3 +8,3 @@ import { ObjectId } from 'mongodb';

export interface JobEntity<
Schedule extends ParsedIntervalSchedule | CronSchedule = ParsedIntervalSchedule | CronSchedule
Schedule extends ParsedIntervalSchedule | CronSchedule = ParsedIntervalSchedule | CronSchedule,
> extends JobDefinition<Schedule> {

@@ -11,0 +11,0 @@ _id?: ObjectId;

import { DateTime } from 'luxon';
import { MongoClient } from 'mongodb';
import { FindOneAndUpdateOptions, MongoClient } from 'mongodb';

@@ -11,2 +11,7 @@ import { ScheduleEntity } from './ScheduleEntity';

const mongoOptions: FindOneAndUpdateOptions & { includeResultMetadata: true } = {
returnDocument: 'after',
includeResultMetadata: true, // ensures backwards compatibility with mongodb <6
};
export class SchedulesRepository extends Repository<ScheduleEntity> {

@@ -20,3 +25,3 @@ private logger: Logger | undefined;

private readonly name: string,
collectionPrefix?: string
collectionPrefix?: string,
) {

@@ -52,5 +57,5 @@ super(mongoClient, SCHEDULES_COLLECTION_NAME, collectionPrefix);

{
...mongoOptions,
upsert: true,
returnDocument: 'after',
}
},
);

@@ -67,3 +72,3 @@

{ scheduleId: this.scheduleId },
error
error,
);

@@ -101,3 +106,3 @@ }

{ $inc: { [`executions.${name}`]: 1 } },
{ returnDocument: 'after' }
mongoOptions,
);

@@ -113,3 +118,3 @@ return { added: schedule.value !== null, running: schedule.value?.executions[name] ?? 0 };

{ $inc: { [`executions.${name}`]: 1 } },
{ returnDocument: 'after' }
mongoOptions,
);

@@ -116,0 +121,0 @@

@@ -30,3 +30,3 @@ import { v4 as uuid } from 'uuid';

pingIntervalMs: number,
private readonly scheduleName: string
private readonly scheduleName: string,
) {

@@ -48,3 +48,3 @@ const schedulesRepository = connection.getSchedulesRepository();

pingIntervalMs,
this.startAllJobs.bind(this)
this.startAllJobs.bind(this),
);

@@ -51,0 +51,0 @@ }

@@ -20,3 +20,3 @@ import { sum } from 'lodash';

private readonly schedulesRepository: SchedulesRepository,
private readonly jobRepository: JobRepository
private readonly jobRepository: JobRepository,
) {

@@ -67,3 +67,3 @@ super();

{ name, maxRunning, ...schedule },
jobResult.error
jobResult.error,
);

@@ -87,3 +87,3 @@ return false;

this.schedulesRepository,
this.jobRepository
this.jobRepository,
);

@@ -123,4 +123,4 @@

this.logger,
'Single execution failed'
)
'Single execution failed',
),
);

@@ -127,0 +127,0 @@ }

@@ -6,5 +6,11 @@ import { SchedulesRepository } from '../repository/SchedulesRepository';

enum StartJobsStatus {
notStarted,
inProgress,
finished,
}
export class SchedulePing {
private handle?: NodeJS.Timeout;
private startedJobs: boolean = false;
private startJobsStatus: StartJobsStatus = StartJobsStatus.notStarted;

@@ -17,3 +23,3 @@ constructor(

private readonly interval: number,
private readonly startAllJobs: () => Promise<void>
private readonly startAllJobs: () => Promise<void>,
) {}

@@ -39,6 +45,10 @@

await this.schedulesRepository.ping(this.scheduleId);
if (!this.startedJobs) {
this.logger.debug(`This schedule just turned active`);
if (this.startJobsStatus === StartJobsStatus.notStarted) {
this.startJobsStatus = StartJobsStatus.inProgress;
this.logger.debug('This schedule just turned active');
await this.startAllJobs();
this.startedJobs = true;
this.startJobsStatus = StartJobsStatus.finished;
this.logger.debug('Finished starting scheduled jobs');
}

@@ -45,0 +55,0 @@ }

@@ -39,3 +39,3 @@ import { max } from 'lodash';

logger,
errorMessage
errorMessage,
);

@@ -42,0 +42,0 @@

@@ -30,5 +30,5 @@ import { DateTime } from 'luxon';

export function toExecutableSchedule(
schedule: ParsedIntervalSchedule | CronSchedule
schedule: ParsedIntervalSchedule | CronSchedule,
): ExecutableIntervalSchedule | ExecutableCronSchedule {
return isCronSchedule(schedule) ? new ExecutableCronSchedule(schedule) : new ExecutableIntervalSchedule(schedule);
}

@@ -27,3 +27,3 @@ import { min } from 'lodash';

private readonly jobRepository: JobRepository,
private readonly logger: Logger
private readonly logger: Logger,
) {}

@@ -36,3 +36,3 @@

schedulesRepository: SchedulesRepository,
jobRepository: JobRepository
jobRepository: JobRepository,
): JobScheduler {

@@ -58,3 +58,3 @@ const executor = new JobExecutor(job.handler, schedulesRepository, jobRepository, logger);

{ name: this.jobName },
momoError.jobNotFound
momoError.jobNotFound,
);

@@ -83,3 +83,3 @@ return;

{ name: this.jobName },
momoError.jobNotFound
momoError.jobNotFound,
);

@@ -122,3 +122,3 @@ return;

{ name: this.jobName },
momoError.jobNotFound
momoError.jobNotFound,
);

@@ -147,3 +147,3 @@ return {

{ name: this.jobName },
momoError.jobNotFound
momoError.jobNotFound,
);

@@ -177,5 +177,5 @@ return;

{ name: this.jobName },
error
error,
);
}
}

@@ -8,3 +8,3 @@ import { Logger } from '../logging/Logger';

logger: Logger,
errorMessage: string
errorMessage: string,
): NodeJS.Timeout {

@@ -24,3 +24,3 @@ return setTimeout(async () => {

logger: Logger,
errorMessage: string
errorMessage: string,
): NodeJS.Timeout {

@@ -27,0 +27,0 @@ return setInterval(async () => {

@@ -13,3 +13,3 @@ import { setSafeInterval, setSafeTimeout } from './safeTimeouts';

logger: Logger,
errorMessage: string
errorMessage: string,
): TimeoutHandle {

@@ -31,5 +31,5 @@ const intervalWithDelay = new IntervalWithDelay(callback, interval, delay, logger, errorMessage);

logger,
errorMessage
errorMessage,
);
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc