const cron = require('cron'); const { model } = require('mongoose'); const schema = require('./event.schema.js'); const LogModel = require('../logs/log.model.js'); const CronJob = cron.CronJob; schema.methods.log = function(message) { const dateOpts = { timeStyle: 'medium', dateStyle: 'short' }; const timestamp = new Date().toLocaleString('en', dateOpts); console.log(`[${timestamp}] ${this.name}: ${message}`); return LogModel.create({ eventId: this._id, message }); }; schema.methods.start = function() { this.log('Event started') this.lastRunAt = new Date(); this.status = 'running'; return this.save(); }; schema.methods.complete = function() { this.log('Event complete') this.status = 'complete'; return this.save(); }; schema.methods.fail = function(error) { this.log(error); this.error = error; this.status = 'failed'; return this.save(); }; schema.methods.computeNextRunAt = function() { const job = new CronJob(this.schedule); const nextRunAt = job.nextDates(); return new Date(nextRunAt); }; schema.pre('save', function(next) { this.nextRunAt = this.computeNextRunAt(); next(); }); schema.statics.findMissedEvents = async function () { return this.find({ nextRunAt: { // TODO: skip single-fire events $lt: new Date() }, }); }; schema.statics.findNextEvents = function(limit = 10) { return this.find( { nextRunAt: { $gt: new Date() }, }, null, { sort: { nextRunAt: 1 }, limit } ) }; const Model = model('Event', schema); module.exports = Model;