Browse Source

refactor for new flitter-DI

tags/v0.5.0
Garrett Mills 2 months ago
parent
commit
1347c84dcb
3 changed files with 55 additions and 137 deletions
  1. 29
    124
      AgendaUnit.js
  2. 18
    12
      Job.js
  3. 8
    1
      templates/Job.js

+ 29
- 124
AgendaUnit.js View File

@@ -1,148 +1,54 @@
/**
* @module flitter-agenda/AgendaUnit
*/


const Unit = require('libflitter/Unit')
const Agenda = require('agenda')
const path = require('path')
const rra = require('recursive-readdir-async')
const Agenda = require('agenda')
const CanonicalUnit = require('libflitter/canon/CanonicalUnit')

/**
* Unit to start the Agenda module.
* Registers & starts the scheduler and loads jobs from the specified directory.
* @extends module:libflitter/Unit~Unit
*/
class AgendaUnit extends Unit {
class AgendaUnit extends CanonicalUnit {
static get name() {
return 'jobs'
}

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()
constructor(directory = './app/jobs') {
super(directory)

/**
* Fully-qualified path to the job files directory.
*
*
* @type {string}
* @name AgendaUnit#directory
* @name AgendaUnitOld#directory
*/
this.directory = path.resolve(directory)
}
/**
* Initialize the unit.
* Creates a new instance of the Agenda scheduler and registers the job files with it.
* The scheduler is then started.
* @param {module:libflitter/app/FlitterApp~FlitterApp} app
* @param {module:libflitter/Context~Context} context
* @returns {Promise<void>}
*/
async go(app, context){

/*
* Create a new instance of the Agenda scheduler.
*/
const sched = new Agenda({}).mongo(app.d.database.connection)
context.bind('scheduler', sched)
app.global.bind('scheduler', sched)
/*
* Load the jobs from the definition files.
*/
await this.load_jobs(sched, app, context)
await sched.start()
}

async cleanup(app){
await app.d.sched.scheduler.stop()
this.canonical_item = 'job'
this.suffix = '.job.js'
}
/**
* Loads the job definition classes from files in this.directory
* and registers them with the scheduler.
* @param {Agenda} sched - the Agenda scheduler
* @param {module:libflitter/app/FlitterApp~FlitterApp} app
* @param {module:libflitter/Context~Context} context
* @returns {Promise<void>}
*/
async load_jobs(sched, app, context){
/*
* Recursively iterate over the files in this.directory
* and load the job definition classes from files that end
* with '.job.js'.
*/
const files = await rra.list(this.directory)
let jobs = {}
app.d.utility.log("Job definitions directory: "+this.directory, 2)
/*
* Iterate over the files by name.
*/
for (let key in files){
if ( files[key].fullname ){
/*
* Only attempt to load a job from files ending with '.job.js'.
*/
if ( files[key].fullname.endsWith('.job.js') ){

/*
* Parse the name of the job from the file name,
* taking into account sub-directories (delineated with ':')
*/
let name = files[key].fullname
.replace(this.directory, '')
.replace(/.job.js/g, '')
.replace(/\//g, ':')
.substr(1)

/*
* Create an instance of the job class,
* store it so it can be accessed globally,
* and register it with the scheduler.
*/
let job_class = require(files[key].fullname)
jobs[name] = new job_class()
sched.define(name, jobs[name].exec)

context.bind('jobs', jobs)
}
}
}
async go(app) {
this.scheduler = new Agenda({}).mongo(this.database.connection)
await super.go(app)
await this.scheduler.start()
}

/**
* Returns the name of the AgendaUnit.
*
* @returns {string} "sched"
*/
name(){
return "sched"
async cleanup(app) {
await this.scheduler.stop()
}

/**
* Returns the directories managed by the AgendaUnit.
* @returns {{jobs: AgendaUnit#directory}}
*/
directories() {
return {
jobs: this.directory,
}
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.
* @returns {{job: {template: ((function(*): string)|*), extension: '.job.js', directory: AgendaUnit#directory}}}
* @returns {{job: {template: ((function(*): string)|*), extension: '.job.js', directory: AgendaUnitOld#directory}}}
*/
templates(){
return {
@@ -153,7 +59,6 @@ class AgendaUnit extends Unit {
},
}
}
}

module.exports = exports = AgendaUnit
module.exports = exports = AgendaUnit

+ 18
- 12
Job.js View File

@@ -2,13 +2,29 @@
* @module flitter-agenda/Job
*/

const { Injectable } = require('flitter-di')

/**
* Parent class to all flitter-agenda job definitions.
* Specifies the method that should be executed when the job is run.
*/
class Job {
class Job extends Injectable {
static get services() {
return [...super.services, 'jobs']
}

/**
* Set by the AgendaUnit when the job is loaded.
* The Flitter canonical name of the job. This is used to
* identify the job class to the Agenda scheduler.
* @type {string}
*/
static JOB_NAME = ''

static async enqueue(when = 'now', data = {}) {
return this.prototype.jobs.scheduler.schedule(when, this.JOB_NAME, data)
}

/**
* Executed when the job is run.
* See the agenda package docs for more info.
@@ -17,16 +33,6 @@ class Job {
* @param {function} done - to be called when the job completes
*/
exec(job, done){
/*
* Do stuff here!
*/
/*
* Whatever you do, it should end by calling this function.
* It may be passed as a callback to another function.
*/
done()
}
}

+ 8
- 1
templates/Job.js View File

@@ -17,6 +17,13 @@ module.exports = exports = function JobTemplateGenerator(name){
* Put some description here!
*/
class ${name}Job extends Job {
/*
* Job classes are injectable, so you can override the
* static services getter here.
*/
static get services() {
return [...super.services, /* other services here */]
}

/*
* Executed when the job is run.
@@ -39,4 +46,4 @@ class ${name}Job extends Job {
}

module.exports = exports = ${name}Job`
}
}

Loading…
Cancel
Save