I'm working on a project with FeathersJS where I have to implement a task scheduler / cron system. Each task is a function with a defined interface (basically a run() method) that gets passed the app object, so different services can be called from the task. Each task can only be called on the server-side. A good example for such a task is the fetching of hourly reports from another api or running a daily health suite.
This basically works but currently I need to register every task as a service in order to have a unified way to call them. My cronjob service calls them via app.service(serviceVarFromJob)[methodVarFromJob].apply() Then I use disallow('external') hooks to prevent the service being used from external providers.
This feels a bit complicated and is probably not the "feathers" way how it's done. Is there some architectural advice on how to register functions in feathers that are not used as a service, but need to make internal service calls?
For example I can register and call a service like this:
app.use("/myservice", new MyService(app));
app.service("myservice").create(..)
Is there a way to extend the app object to hold a reference to all certain functions that I register, like:
app.registerFunction("myTask", new MyTask(app));
const task = app.task("mytask");
await task.run()
I have looked for plugin documentation in order to see whether I could implement this myself, but haven't found any regarding this.
For anyone omming here,
I use cron-job-manager for this.
# app.js
const CronJobManager = require('cron-job-manager');
global.cronJobManager = new CronJobManager();
cronJobManager.add(
`cronjobs/fetchAll`, '*/10 * * * *',
() => { this.fetchAll(); },
{ start: true, timeZone: 'Europe/Berlin' });
/**
* @summary Save all currently registered cronjobs to the database
*
* @description This function is called by the cronjob manager x minutes
* and saves all cronjobs with their current state to to the database.
*
*/
async fetchAll() {
try {
for (const [key, job] of Object.entries(cronJobManager.jobs)) {
let entry = {
name: key,
nextDate: job.nextDate(),
lastDate: job.lastDate(),
active: job.running,
};
await this.models.sys_cronJobs.upsert(entry);
}
} catch (error) {
console.log('Cron fetchAll failed: ', error);
}
}
const Sequelize = require('sequelize');
const DataTypes = Sequelize.DataTypes;
module.exports = function (app) {
const sequelizeClient = app.get('sequelizeClient');
const sysCronJobs = sequelizeClient.define('sys_cronJobs', {
name: {
type: DataTypes.STRING,
allowNull: false,
unique: {
args: true,
name: 'name',
msg: "Schlüssel bereits vorhanden!"
},
},
logs: {
type: DataTypes.TEXT,
allowNull: true,
},
nextDate: {
type: DataTypes.DATE,
allowNull: true,
},
lastDate: {
type: DataTypes.DATE,
allowNull: true,
},
active: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
}
}, {
timestamps: true,
indexes: [{
fields: ['name']
}],
});
return sysCronJobs;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With