flitter-agenda

An Agenda-based task scheduler for Flitter.

Overview

flitter-agenda provides a wrapper for the Agenda scheduler. This allows jobs to be defined and scheduled programmatically, and persistently. It uses the same MongoDB database as the rest of the Flitter application.

For the most part, using flitter-agenda is identical to using vanilla Agenda. The only main difference is that jobs should be defined in individual files in a given directory (by default, app/jobs). Each of these files should export a class that extends flitter-agenda/Job. The name of a job is parsed from its file name, recursively. flitter-agenda uses the Flitter convention for sub-directory naming, meaning that sub-directories are delineated with a : character. For example, the job named auth:CleanUsers would be located in the file app/jobs/auth/CleanUsers.job.js.

Installation

flitter-agenda doesn't ship with Flitter by default, but it's pretty easy to add. First, install the package:

yarn add flitter-agenda

Now, modify the Units.flitter.js file. Add the add the following line to the "Custom Flitter Units" section to tell Flitter to load flitter-agenda:

'Agenda'		: new (require('flitter-agenda/AgendaUnit'))(),

Et voilà! You should now have access to flitter-agenda.

Creating a Sample Job

As an example, we'll create a sample job that prints a some text to the console.

First, create a new job definition file. We can do this using the built in template with the ./flitter command:

./flitter new job Log

This will create the file app/jobs/Log.job.js. Open it up, and define the actual logic for the job:

const Job = require('flitter-agenda/Job')

class LogJob extends Job {

    exec(job, done){
        
        const {msg} = job.attrs.data
        log(msg)
        
        done()
    }
}

module.exports = exports = LogJob

Here, we take the job argument msg and pass it to Flitter's log() function.

We can test out our job by running it from the Flitter shell. Here's a sample output:

sh-4.4$ ./flitter shell
powered by Flitter, © 2019 Garrett Mills
(flitter)> _flit.sched.scheduler.schedule('in 3 seconds', 'Log', {msg: "This is a message!"})
Promise { <pending> }
(flitter)> This is a message!

_flit.sched.scheduler is the running instance of Agenda, so you can call any function on it like you normally would such as schedule(), every(), even define(). (See the Agenda docs.) Here, we scheduled the Log job we created to run 3 seconds after the schedule() function is called, and passed it a message.

The Agenda Unit

flitter-agenda/AgendaUnit

exports:  AgendaUnit

class AgendaUnit

extends:  libflitter/Unit

Initializes the Agenda scheduler for Flitter. Loads job definitions from the specified directory of classes which extend flitter-agenda/Job and registers them with the scheduler. Starts the scheduler. This establishes the Agenda context and calls the next function under it.

directory

type:  String

Fully-qualified path to the folder where the job definition class files are stored.

constructor(String directory = './app/jobs')

returns:  this

Initializes the class. Resolves the provided directory and stores it in this.directory.

go(express app, function next)

returns:  undefined

Initializes the unit. Creates a new Agenda scheduler and connects it to the MongoDB server. Creates the _flit.sched object, then calls this.load_jobs() and passes it the scheduler and the next function in the stack.

load_jobs(agenda sched, function next)

returns:  undefined

Loads the job definition classes from the files in this.directory that end with the .job.js extension, recursively. Each job is assigned a name which is parsed from the file name and sub-directory. flitter-agenda follows the Flitter convention for sub-directory naming -- sub-directories are delineated with a : character. For example, the file app/jobs/auth/CleanUsers.job.js would be named auth:CleanUsers. These job classes are initialized and registered with the scheduler. Finally, this.daemon() is called and passed the next function.

daemon(function next)

returns:  undefined

Starts the scheduler. Once that has completed, it calls the next function from within that context.

provides()

returns:  Object

Returns an Object describing the services, templates, and directories provided by this unit. They are as follows:

Type Key Value Notes
Service Name name "flitter-agenda" The name of the service. This is added to the _flit.services array so other units can check for this unit.
Directory directories.jobs this.directory The fully-qualified path of the job definition files. This is added to the _flit.directories store so other units can access it.
Template templates.job Object Template that creates new job definition file in this.directory.

Agenda Context

Guarantees that the job definitions have been loaded and registered with the scheduler and that the scheduler has been started.

_flit.sched

type:  Object

Holds the variables and functions provided by this unit.

_flit.sched.scheduler

type:  agenda

Instance of the Agenda scheduler. The scheduler has already been started via the start() method. This can be used to schedule and manage jobs as per the Agenda docs.

_flit.sched.jobs

type:  Object

Set of key-value pairs such that the value is an instance of flitter-agenda/Job, and the value is the name of the job. Job names are parsed from file names and follow the Flitter convention for sub-directory naming. That is, sub-directories should be delineated with a : character. For example, the job defined in the file app/jobs/auth/CleanUsers.job.js would be named auth:CleanUsers.

The Job Definition Class

flitter-agenda/Job

exports:  Job

class Job

Defines a job that is registered with the Agenda scheduler when flitter-agenda is loaded.

exec(agenda.job job, function done)

returns:  undefined

Does the job. This is executed by the scheduler when the job is run.