Electrician
... will sort out your wiring.
Electrician is a module for wiring together systems composed of components. In
order for a component to play well with electrician, it needs to support a
simple interface. Components supporting this interface are called electric
components. Electric component should define a way to be started (start
function), a way to be stopped (stop
function) and list its dependencies
(dependsOn
property). Electrician can then wire these components into a system
(which is itself an electric component).
When system is started, electrician ensures that all the components are started in correct dependency order, and it passes all dependencies down to components start functions.
Conversely when system is stopped all the components are stopped in reverse order.
It is probably the easiest to just show an example...
Usage
Example
Given a system composed of four components A, B, C and D. Where component A has no dependencies. Component B depends on components A and C. Component C depends on component A. And component D depends on component C.
We'd like to be able to start and stop the system in the right order and pass the right dependencies to individual components.
Topology
+---+ +---+ +---+
| A |<----+| C |<----+| D |
+---+ +---+ +---+
^ ^
| |
| +---+
+-------+| B |
+---+
Code
'use strict'; // COMPONENTS IMPLEMENTATIONS { thisname = name; return this;}NoDepComponentprototype { console; ;}NoDepComponentprototypestop = stop;NoDepComponentprototypetoString = toString; { thisname = name; thisdependsOn = dep return this;}OneDepComponentprototype { console; console; ;}OneDepComponentprototypestop = stop;OneDepComponentprototypetoString = toString; { thisname = name; thisdependsOn = firstDep secondDep return this;}TwoDepComponentprototype { console; console; console; ;}TwoDepComponentprototypestop = stop;TwoDepComponentprototypetoString = toString; { console; ;} { return 'Component ' + thisname;} // COMPOSE SYSTEMvar system = electrician; // START SYSTEM// callback versionsystemstart { if err return console; console;}; // promise versionsystem start // STOP SYSTEM// callback versionsystem; // promise versionsystem
Output
Starting: Component A
Starting: Component C
Dependency: Component A
Starting: Component B
1st dependency: Component A
2nd dependency: Component C
Starting: Component D
Dependency: Component C
System started
Stopping: Component D
Stopping: Component B
Stopping: Component C
Stopping: Component A
System stopped
Electric component interface
dependsOn
Array of dependency names. Used to determine starting order of components and
to inject dependencies into start
function of given component.
Example
thisdependsOn = 'rabbitmq' 'redis';
start([dependencies], next)
Function used to start the component. Electrician will call this function after
all the dependencies of component were started and pass them as arguments.
Arguments will be passed in order declared in dependsOn
property. If
function declares fewer dependencies than declared in dependsOn
, then only
as many dependencies as there are available arguments will be passed (last
argument is persumed to be a callback). This facilitates being able to declare
dependencies that you wish to be started before the component, but you don't
intend on using directly (e.g. environment setup).
When component is successfully started, an instance of it should be given to
next
callback so it can be passed to components depending on it.
Arguments
[dependencies]
(...Object) Dependency componentsnext
Callback to export started component or notify of failure
Example
this { app; app; appstart { if err return ; ; };};
stop(next)
Function used to stop the component. Electrician will call this function after all the components that depend on this component were stopped.
Arguments
next
Callback to notify of successful stop or failure
Example
this { app;};
Electrician system interface
System is a supercomponent composed of components wired together by electrician.
system(componentMap)
Creates a system composed of components provided in componentMap
. Map keys
are considered component names (that can be used when declaring dependencies
in dependsOn
). While values are instances of components themselves.
Example
var config = ;var Application = ;var Redis = ;var RabbitMq = ; var electrician = ; var system = electrician;
System instance interface
System is essentially a component with no declared dependencies (no dependsOn
property). Thus it can be started and stopped by the same start
/stop
functions.
start(next)
Starts the system (all the components it is composed of).
If next
is passed in, calls next
when done or on failure.
If next
is not passed in, returns a resolved Promise when done or a rejected one on failure.
Arguments
next
Callback to notify of successful start or failure. If not passed in, method returns a promise.
Example
// callback versionsystemstart { if err return console; console;}; // promise versionsystem start
stop(next)
Stops the system (all the components it is composed of).
If next
is passed in, calls next
when done or on failure.
If next
is not passed in, returns a resolved Promise when done or a rejected one on failure.
Arguments
next
Callback to notify of successful stop or failure. If not passed in, method returns a promise.
Example
// callback versionsystem; // promise versionsystem ;