Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

feathers architecture task functions

Tags:

feathersjs

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.

like image 766
florian norbert bepunkt Avatar asked Jun 28 '26 14:06

florian norbert bepunkt


1 Answers

For anyone omming here, I use cron-job-manager for this.

# app.js
const CronJobManager = require('cron-job-manager');

global.cronJobManager = new CronJobManager();

Register a new cronjob

        cronJobManager.add(
            `cronjobs/fetchAll`, '*/10 * * * *',
            () => { this.fetchAll(); },
            { start: true, timeZone: 'Europe/Berlin' });

Get all registered cronjobs

/**
     * @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);
        }
    }

Model for database

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;
};
like image 167
Daniel Böttner Avatar answered Jul 01 '26 21:07

Daniel Böttner