aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreug-vs <eug-vs@keemail.me>2020-12-02 03:09:53 +0300
committereug-vs <eug-vs@keemail.me>2020-12-02 03:09:53 +0300
commit91784c9e8d6c0565d001f60d5969ea7618e4a61f (patch)
tree62cd808172e4066f12cea7a63bf4d996482c27ee
parent2069909287866003d63e9ea7862b2273ec73e2d5 (diff)
downloadmongo-cronjob-91784c9e8d6c0565d001f60d5969ea7618e4a61f.tar.gz
feat: dynamically register handlers
-rw-r--r--lib/event.model.ts7
-rw-r--r--lib/event.schema.ts4
-rw-r--r--lib/scheduler.ts27
3 files changed, 25 insertions, 13 deletions
diff --git a/lib/event.model.ts b/lib/event.model.ts
index a430674..7768ffc 100644
--- a/lib/event.model.ts
+++ b/lib/event.model.ts
@@ -4,11 +4,11 @@ import createEventSchema, { EventDocument } from './event.schema';
import { LogDocument } from './log.schema';
import LogModel from './log.model';
-interface Event<Context> extends EventDocument<Context> {
+export interface Event<Context> extends EventDocument<Context> {
log(message: string): void;
start(): void;
complete(): void;
- fail(error: Error): void;
+ fail(error: Error | string): void;
computeNextRunAt(): Date;
getLogs(): Promise<LogDocument[]>;
}
@@ -26,7 +26,7 @@ const createEventModel = <Context>(name: string, contextSchema: Schema): EventMo
// Schema methods
schema.method('log', function(message: string) {
const timestamp = new Date().toLocaleString('en');
- console.log(`[${timestamp}] ${this.name}: ${message}`);
+ console.log(`[${timestamp}] ${this.type}: ${message}`);
return LogModel.create({ eventId: this._id, message });
});
@@ -45,6 +45,7 @@ const createEventModel = <Context>(name: string, contextSchema: Schema): EventMo
schema.method('fail', function(error: Error) {
this.log(error);
+ this.log('Event failed');
this.error = error;
this.status = 'failed';
return this.save();
diff --git a/lib/event.schema.ts b/lib/event.schema.ts
index 1bba77d..0f428fd 100644
--- a/lib/event.schema.ts
+++ b/lib/event.schema.ts
@@ -1,7 +1,7 @@
import { Schema, Document } from 'mongoose';
export interface EventDocument<Context> extends Document {
- name: string;
+ type: string;
schedule: string;
status: 'notStarted' | 'running' | 'complete' | 'failed';
error?: string;
@@ -11,7 +11,7 @@ export interface EventDocument<Context> extends Document {
}
const createEventSchema = (contextSchema: Schema) => new Schema({
- name: {
+ type: {
type: String,
required: true
},
diff --git a/lib/scheduler.ts b/lib/scheduler.ts
index 1d52c35..064daa8 100644
--- a/lib/scheduler.ts
+++ b/lib/scheduler.ts
@@ -1,6 +1,8 @@
import cron from 'cron';
import Bluebird from 'bluebird';
-import { EventModel } from './event.model';
+import { EventModel, Event } from './event.model';
+
+export type Handler = (event: Event<any>) => void;
const CronJob = cron.CronJob;
@@ -11,15 +13,21 @@ class Scheduler {
job: cron.CronJob;
jobs: cron.CronJob[];
Model: EventModel<any>;
+ handlers: Record<string, Handler>;
constructor(model: EventModel<any>, pollingInterval = defaultPollingInterval) {
this.Model = model;
this.jobs = [];
+ this.handlers = {};
this.job = new CronJob(pollingInterval, () => this.updateJobs());
this.startPolling();
}
+ registerHandler(name: string, handler: Handler) {
+ this.handlers[name] = handler;
+ }
+
startPolling() {
this.job.start();
}
@@ -61,16 +69,19 @@ class Scheduler {
async run(id: string) {
const event = await this.Model.findById(id);
- // TODO: handle the case when event is deleted
- if (!event) return;
+ if (!event) return console.log('WARNING: locked event does not exist');
try {
- event.start();
- // TODO: put actual handler here
- await new Promise(res => setTimeout(res, 5000));
- return event.complete();
+ const handleEvent = this.handlers[event.type];
+
+ if (handleEvent) {
+ event.start();
+ await handleEvent(event);
+ return event.complete();
+ } else throw new Error('No handler found')
+
} catch (error) {
- event.fail(error);
+ return event.fail(error);
}
}
}