agenda/AgendaUnit.js

/**
 * @module flitter-agenda/AgendaUnit
 */

const Agenda = require('agenda')
const CanonicalUnit = require('libflitter/canon/CanonicalUnit')

/**
 * Unit service to for the Agenda scheduler. On load, it registers
 * jobs from the configured directory (usually './app/jobs') and starts
 * the job queue.
 * @extends module:libflitter/canon/CanonicalUnit~CanonicalUnit
 */
class AgendaUnit extends CanonicalUnit {

    /**
     * Get the name of this service: 'jobs'
     * @returns {string} - 'jobs'
     */
    static get name() {
        return 'jobs'
    }

    /**
     * Define the services required by this unit.
     * @returns {Array<string>}
     */
    static get services() {
        return [...super.services, 'database']
    }

    /**
     * Initialize the class.
     * Resolves and stores the directory containing the job definition files.
     * @param {string} directory - Directory containing the job definition files.
     */
    constructor(directory = './app/jobs') {
        super(directory)

        /**
         * Fully-qualified path to the job files directory.
         *
         * @type {string}
         * @name AgendaUnitOld#directory
         */

        /**
         * Name of the unit's canonical item - 'job'
         * @type {string} - 'job'
         */
        this.canonical_item = 'job'

        /**
         * File suffix for the unit's files - '.job.js'
         * @type {string} - '.job.js'
         */
        this.suffix = '.job.js'
    }

    /**
     * Initialize the jobs service. Creates a new Agenda scheduler and
     * registers the jobs in the canonical directory for this unit.
     * @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app
     * @returns {Promise<void>}
     */
    async go(app) {
        this.scheduler = new Agenda({}).mongo(this.database.connection)
        await super.go(app)
        await this.scheduler.start()
    }

    /**
     * Clean up the resources managed by this unit. Stops the scheduler.
     * @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app
     * @returns {Promise<void>}
     */
    async cleanup(app) {
        await this.scheduler.stop()
    }

    /**
     * Initialize a single canonical file loaded by the unit.
     * Defines a job in the scheduler using the exec method on the job's
     * class definition.
     * @param {module:libflitter/app/FlitterApp~FlitterApp} app - the Flitter app
     * @param {string} name - the unqualified canonical name of the file
     * @param {module:flitter-agenda/Job~Job} instance - include from the file; should be a class definition of the Job
     * @returns {Promise<module:flitter-agenda/Job~Job>}
     */
    async init_canonical_file({app, name, instance}) {
        instance.JOB_NAME = name
        const job_instance = new instance()
        this.scheduler.define(name, job_instance.exec.bind(job_instance))
        return instance
    }

    /**
     * Returns the templates managed by the AgendaUnit.
     * Provides the 'job' template.
     * @returns {object}
     */
    templates(){
        return {
            job: {
                template: require('./templates/Job'),
                directory: this.directory,
                extension: '.job.js',
            },
        }
    }
}

module.exports = exports = AgendaUnit