UNPKG

auto-daemon

Version:

automatically spawn implicit background services

157 lines (118 loc) 4.25 kB
# auto-daemon automatically spawn implicit background services # example First, the command line interface wires up actions for each command and loads the auto-daemon module: ``` js #!/usr/bin/env node var autod = require('auto-daemon'); var opts = { rpcfile: __dirname + '/iface.js', sockfile: '/tmp/whatever.sock', methods: [ 'add', 'get', 'close' ] }; var cmd = process.argv[2]; autod(opts, function (err, r, c) { if (err) { console.error(err); } else if (cmd === 'add') { var n = Number(process.argv[3]); r.add(n, function (res) { console.log(res); c.destroy(); }); } else if (cmd === 'get') { r.get(function (res) { console.log(res); c.destroy(); }); } else if (cmd === 'close') { r.close(); } }); ``` Next, the `iface.js` provides the interfaces and stores the state: ``` js var n = 0; module.exports = function (server, stream) { return { add: function (m, cb) { cb(n += m) }, get: function (cb) { cb(n) }, close: function () { server.close(); stream.destroy() } } }; ``` Now the first time the command is run, a daemon is implicitly launched in the background. When the server is shutdown with `close`, the state is reset as a new server is implicitly created on the next action: ``` $ node cmd.js add 2 2 $ node cmd.js add 3 5 $ node cmd.js add 4 9 $ node cmd.js close $ node cmd.js add 5 5 ``` # methods ``` js var autod = require('auto-daemon') var createServer = require('auto-daemon/server') var listen = require('auto-daemon/listen') ``` ## var d = autod(opts, cb) Connect to a daemon instance, spawning the daemon first if it isn't already running. `cb(err, rpc, connection)` fires with the rpc interface to call methods on and the unix socket connection instance. * `opts.rpcfile` - file that exports an rpc interface (required) * `opts.methods` - an array of methods to expose (required) * `opts.sockfile` - file to use as the unix socket (required) * `opts.autoclose` - if `true`, close the server when the refcount drops to 0 * `opts.debug` - when `true`, forward stdout and stderr in the daemonized process to the local stdout and stderr * `opts.args` - an array of extra arguments to pass as the third argument to the interface. Must serialize as process arguments. * `opts.execPath` - a string path to spawn. Default: `process.execPath` * `opts.cwd` - working directory to pass through to `spawn()` * `opts.env` - environment to pass through the `spawn()` * `opts.exit` - when autoclosing, call `process.exit()` to force a process exit The daemon refcount goes up by 1 for each connection and drops by 1 when a client disconnects. If the object returned by the rpc interface is an event emitter, it can emit `'ref`' events to increment the refcount and `'unref'` events to decrement the refcount. The method format is the same as [multiplex-rpc](https://npmjs.com/package/multiplex-rpc): methods that end in `:s` are interpreted as stream methods. ## d.on('process', ps) Get a handle to spawned processes. ## var server = createServer(createIface, opts) Use this method if you'd rather create the server yourself. This is useful if you want the server to listen in the foreground. Pass in the `createIface` function, which should be the same value as requiring an rpc file. `opts.autoclose` behaves the same as with `autod()`. ## var server = listen(createIface, opts) Create and listen on a unix socket `opts.sockfile`. The process id is written to `opts.pidfile`. The server emits a `ready` event when the pidfile has been written. # rpc interface The rpc file should export a function that returns an object. The function will be called like so: ``` js var createIface = require(rpcfile); var iface = createIface(server, stream, args) ``` and should return the rpc methods in `iface` for that connection. * `server` is the daemon server instance * `stream` is the stream for the current session * `args` is an array of extra arguments provided by `opts.args` If the method is a stream method, it should return a stream. Otherwise methods can accept a callback as their last argument. # license MIT