create analyzer

master
garrettmills 4 years ago
parent b955996654
commit 30f30f5083

@ -19,6 +19,14 @@ class Unit extends Service {
return [...super.services, 'app']
}
/**
* Names of additional services provided by this unit.
* @returns {Array<string>}
*/
static get provides() {
return []
}
static STATUS_STOPPED = 'stopped'
static STATUS_STARTING = 'starting'
static STATUS_RUNNING = 'running'

@ -0,0 +1,47 @@
/**
* @module libflitter/app/Analyzer
*/
const color = require('colors/safe')
/**
* Analyzes various aspects of the application and its dependencies.
*/
class Analyzer {
constructor(app, units) {
/**
* The application in question.
* @type {module:libflitter/app/FlitterApp~FlitterApp}
*/
this.app = app
/**
* Collection of unit definitions used by the application.
* @type {object}
*/
this.units = units
}
/**
* Check the services and dependencies of each unit and ensure that none request
* a service that has not been provided by the time the unit starts.
*/
check_dependencies() {
const available_services = ['app']
for ( const UnitClass of Object.values(this.units) ) {
for ( const service of UnitClass.services ) {
if ( !available_services.includes(service) ) {
const message = ` ${color.red('UNIT DEPENDENCY ERROR:')} ${UnitClass.name} depends on ${service}, but it is not registered when the unit tries to start.`
console.log(message)
console.log(`If the unit depends on a service provided by a later unit, try moving ${UnitClass.name} below that unit.`)
throw new Error(message)
}
}
available_services.push(UnitClass.name)
if ( UnitClass.provides ) UnitClass.provides.forEach(s => available_services.push(s))
}
}
}
module.exports = exports = Analyzer

@ -6,6 +6,7 @@ const { Container, DependencyInjector } = require('flitter-di')
const Service = require('../NamedService')
const output = new (require('../utility/services/Output.service'))()
const Unit = require('../Unit')
const Analyzer = require('./Analyzer')
/**
* The Flitter application.
@ -20,6 +21,13 @@ class FlitterApp extends Service {
return 'app'
}
/**
* If true, the {@link module:libflitter/app/Analyzer~Analyzer} will check
* the application dependencies before run.
* @type {boolean}
*/
enable_analyzer = true
/**
* Instantiate the application.
* @param {object} units - mapping of names to static Unit CLASS definitions
@ -59,6 +67,12 @@ class FlitterApp extends Service {
* @type {express}
*/
this.express = require('express')()
/**
* Analyzer used to process various aspects of the application.
* @type {module:libflitter/app/Analyzer~Analyzer}
*/
this.analyzer = new Analyzer(this, units)
}
/**
@ -83,7 +97,7 @@ class FlitterApp extends Service {
* @returns {Promise<void>}
*/
async run() {
await this.up()
await this.up().catch(e => { throw e })
await this.down()
}
@ -94,6 +108,8 @@ class FlitterApp extends Service {
async up() {
this.output.message('Starting Flitter...', 0)
if ( this.enable_analyzer ) this.analyzer.check_dependencies()
// Start the units
for ( const unit_name of this.__unit_array ) {
const unit = this.__di.service(unit_name)

@ -24,6 +24,14 @@ class UtilityUnit extends Unit {
return [...super.services, 'configs']
}
/**
* Array of additional service names provided by this unit.
* @returns {Array<string>}
*/
static get provides() {
return ['output']
}
/**
* Gets the name of the service provided by this unit: 'utility'
* @returns {string} - 'utility'

Loading…
Cancel
Save