ironworks is a worker (plug-in) based framework to assist in creating a modular, interconnected microservice ecosystem
it provides several built-in workers as well as a base class to create custom workers
Documentation (coming soon)
npm install ironworks
- a
Service
is a container for workers - a
Worker
is added to aService
using theuse(worker)
method - when all workers are added, call the
start()
method - when a
Service
is started, it calls workflow methods on each worker:preInit(comm, whoService, [callback])
- this is mainly an internal step - it should not be overridden under normal circumstances
comm
is the instance ofiron-beam
that serves as ironworks shared eventing enginewhoService
is an object with the name and id of the servicecallback
accepts an error parameter- always
return super.preInit(comm, whoService, [callback])
from this method
init([callback])
- this is the step where listeners are created
- listeners can be created after this step, but certain
Service
features will not take them into account callback
accepts an error parameter- always
return super.init([callback])
from this method
postInit([dependencies], [callback])
- this step is used to interact with other workers once they have created their listeners in
init
dependencies
will be aCollection
of workers that this worker depends on - those workers will have already completed theirpostInit
stepcallback
accepts an error parameter- always
return super.postInit([dependencies], [callback])
from this method
- this step is used to interact with other workers once they have created their listeners in
start([dependencies], [callback])
- this step is used to interact with other workers once they have be started
dependencies
will be aCollection
of workers that this worker depends on - those workers will have already completed theirstart
stepcallback
accepts an error parameter- always
return super.start([dependencies], [callback])
from this method
postStart([dependencies], [callback])
- this step is used to interact with other workers after they have been started
dependencies
will be aCollection
of workers that this worker depends on - those workers will have already completed theirpostStart
stepcallback
accepts an error parameter- always
return super.postStart([dependencies], [callback])
from this method
- call
getWorker(name, callback)
to get a worker from a started service - callback accepts an error and the worker, if found - call
dispose([callback])
to stop a service which will dispose it's workers and release it's listeners and other references - callback is optional and does not accept an error parameter (disposal errors are handled internally through stdout)
- a
Worker
is a class that overrides service workflow methods in order to add event listeners to accomplish some task- eventing methods - ironworks uses 6 pairs of methods for emitters/listeners, instead of just emit/on, so that the parameter signature will be known to the framework
tell('event')
->listen('event')
- the simplest form where no information is sent or received - the event occurence is all that is needed
inform('information', { some: 'info' })
->info('information', (info) => {...})
- the emitter is providing information to the listener
confirm('task', (e) => {...})
->verify('task', (cb) => {...})
- the emitter needs to know when a listener has performed it's task
check('receipt', { product: 'data' }, (e) => {...})
->ack('receipt', (product, cb) => {...})
- the emitter needs to know when a listener has performed it's task on the provided information
ask('question', (e, answer) => {...})
->answer('question', (cb) => {...})
- the emitter needs information from the listener
request('action', { request: 'data' }, (e, response) => {...}
->respond('action', (req, cb) => {...})
- the emitter needs to get information from a listener about the provided information
- eventing methods - ironworks uses 6 pairs of methods for emitters/listeners, instead of just emit/on, so that the parameter signature will be known to the framework
ironworks uses a 5 part namespce for all event names - (i.e. - comm.service-name.request.my-worker.do-task
)
- prefix
- used to create distinct channels for events inside the same service
- defaults to 'comm'
- service
- used to identify the target service name when communicating between mulitple services
- method
- the name of the "emit" method name used (i.e. - request, tell, check, etc.)
- worker
- the worker name that houses the listener for the event
- name
- the name of the event
- http server
- can be used to serve static files
- can provide a REST api for all listeners not annotated with
{ internal: true }
- socket
- depends on
HttpServerWorker
- can be used to receive communication from other ironworks services via
ConnectorWorker
- can provide a
socket.io
api for all listeners not annotated with{ internal: true }
- depends on
- auth
- depends on
HttpServerWorker
andSocketWorker
- can authenticate event listener endpoints using jwt tokens
- can authorize event listeners endpoints using roles
- depends on
- log
- will log all events to stdout
- events can be annotated
{ log: { level: [detail number] } }
to control the detail level of the logs
- metric
- will emit
comm.[service name].inform.iw-metric-[metric worker name].increment
for every event so that counts can be calculated - will emit
comm.[service name].inform.iw-metric-[metric worker name].duration
for every event so that execution time averages can be calculated
- will emit
- connector
- used to connect to other ironworks services
- more to come!
- environment
- used to get environment variables from the system
import ironworks = require('ironworks');
import Service = ironworks.service.Service;
import HttpServerWorker = ironworks.workers.HttpServerWorker;
new Service('my-file-server')
.use(new HttpServerWorker({
port: 9967,
rootSitePagePath: "index.html", //the file served for the site root
hapi: { // this entire object is passed to hapi, any valid hapi option can be used
connections: {
routes: {
files: {
relativeTo: path.resolve('./content/public')
}
}
}
}
})
.start();
import ironworks = require('ironworks');
import Service = ironworks.service.Service;
import HttpServerWorker = ironworks.workers.HttpServerWorker;
new Service('my-api-service')
.use(new HttpServerWorker({
port: 9967,
apiRoute: 'api' // used to separate the ironworks REST endpoints from your other urls
})
.answer('echo-endpoint', (req, cb) => {
cb(null, req);
}) // this will create an endpoint at http://hostname:9967/api/comm/my-api-service/ask/iw-service/echo-endpoint?some=data
.start();