embark-area-51/lib/core/processes/processManager.js

107 lines
2.7 KiB
JavaScript
Raw Normal View History

feat(core/processManager): introduce `processes:stop` handlers So far, `ProcessManager` was able to only register a `process:launch` handler. There was no way to tell `ProcessManager` how to stop processes. This hasn't been a problem so far as most of the service processes can be started without the usage of the `ProcessManager`, but turns out to be necessary if we want Embark UI to be able to pick up running services. A good example is the webserver process, which until now bypasses the `ProcessManager` all together. The webserver sets up two event handlers to start and stop it respectively: ``` this.events.setCommandHandler('start-webserver', () => this.server.start()); this.events.setCommandHandler('stop-webserver', () => this.server.stop()); ``` In the future, this should happen through the `ProcessManager` instead, so the webserver process can be picked up by Embark UI, like this: ``` this.request('process:register', 'webserver', () => { this.server.start(); }); // and then this.request('process:launch', 'webserver', () => { // server started }); ``` Notice that the given callback to registering a process is actually the function that gets called to launch the process. Having that in mind, and considering that we also need a way to stop the process through `ProcessManager, so we don't introduce a regression, we need a way to register a stop call back as well. The new API introduced in this commit looks like this: ``` this.request('process:register', 'webserver', { launchFn: (callback) => { this.server.start(callback) }, stopFn: (callback) => this.server.stop(callback) } }); // and then this.request('process:launch', 'webserver', (err, message, port) => { // server started }); this.request('process:stop', 'webserver', err => { // server stopped }); ``` Notice that `process:register` works exactly the same way as before as well. Another thing to notice is that all parameters emitted by the underlying process are propagated to the outside caller, which is why `err`, `message` and `port` are available inside the launch callback.
2018-10-11 12:46:57 +00:00
const ProcessState = {
Unstarted: 'unstarted',
Starting: 'starting',
Running: 'running',
Stopping: 'stopping',
}
class ProcessManager {
constructor(options) {
this.logger = options.logger;
this.events = options.events;
this.plugins = options.plugins;
this.processes = {};
2018-08-01 15:14:02 +00:00
this._registerAsPlugin();
this._registerEvents();
}
_registerAsPlugin() {
const self = this;
2018-08-01 15:14:02 +00:00
self.plugin = this.plugins.createPlugin('processManager', {});
2018-10-17 22:36:46 +00:00
this.servicesState = {}
this.events.on("servicesState", (servicesState) => {
this.servicesState = servicesState;
})
self.plugin.registerAPICall(
'get',
'/embark-api/services',
(req, res) => {
let processList = []
for (let serviceName in this.servicesState) {
let service = this.servicesState[serviceName]
processList.push({state: service.status, name: serviceName, description: service.name})
}
res.send(processList)
}
);
2018-08-01 15:14:02 +00:00
self.plugin.registerAPICall(
'get',
2018-08-01 16:53:37 +00:00
'/embark-api/processes',
2018-08-01 15:14:02 +00:00
(req, res) => {
2018-08-07 14:09:55 +00:00
const formatter = (acc, processName) => {
acc.push({state: self.processes[processName].state, name: processName});
return acc;
};
res.send(Object.keys(self.processes).reduce(formatter, []));
2018-08-01 15:14:02 +00:00
}
);
}
_registerEvents() {
const self = this;
self.events.setCommandHandler('processes:register', (name, cb) => {
feat(core/processManager): introduce `processes:stop` handlers So far, `ProcessManager` was able to only register a `process:launch` handler. There was no way to tell `ProcessManager` how to stop processes. This hasn't been a problem so far as most of the service processes can be started without the usage of the `ProcessManager`, but turns out to be necessary if we want Embark UI to be able to pick up running services. A good example is the webserver process, which until now bypasses the `ProcessManager` all together. The webserver sets up two event handlers to start and stop it respectively: ``` this.events.setCommandHandler('start-webserver', () => this.server.start()); this.events.setCommandHandler('stop-webserver', () => this.server.stop()); ``` In the future, this should happen through the `ProcessManager` instead, so the webserver process can be picked up by Embark UI, like this: ``` this.request('process:register', 'webserver', () => { this.server.start(); }); // and then this.request('process:launch', 'webserver', () => { // server started }); ``` Notice that the given callback to registering a process is actually the function that gets called to launch the process. Having that in mind, and considering that we also need a way to stop the process through `ProcessManager, so we don't introduce a regression, we need a way to register a stop call back as well. The new API introduced in this commit looks like this: ``` this.request('process:register', 'webserver', { launchFn: (callback) => { this.server.start(callback) }, stopFn: (callback) => this.server.stop(callback) } }); // and then this.request('process:launch', 'webserver', (err, message, port) => { // server started }); this.request('process:stop', 'webserver', err => { // server stopped }); ``` Notice that `process:register` works exactly the same way as before as well. Another thing to notice is that all parameters emitted by the underlying process are propagated to the outside caller, which is why `err`, `message` and `port` are available inside the launch callback.
2018-10-11 12:46:57 +00:00
let launchFn, stopFn;
if (typeof cb === 'object') {
launchFn = cb.launchFn;
stopFn = cb.stopFn;
}
this.processes[name] = {
feat(core/processManager): introduce `processes:stop` handlers So far, `ProcessManager` was able to only register a `process:launch` handler. There was no way to tell `ProcessManager` how to stop processes. This hasn't been a problem so far as most of the service processes can be started without the usage of the `ProcessManager`, but turns out to be necessary if we want Embark UI to be able to pick up running services. A good example is the webserver process, which until now bypasses the `ProcessManager` all together. The webserver sets up two event handlers to start and stop it respectively: ``` this.events.setCommandHandler('start-webserver', () => this.server.start()); this.events.setCommandHandler('stop-webserver', () => this.server.stop()); ``` In the future, this should happen through the `ProcessManager` instead, so the webserver process can be picked up by Embark UI, like this: ``` this.request('process:register', 'webserver', () => { this.server.start(); }); // and then this.request('process:launch', 'webserver', () => { // server started }); ``` Notice that the given callback to registering a process is actually the function that gets called to launch the process. Having that in mind, and considering that we also need a way to stop the process through `ProcessManager, so we don't introduce a regression, we need a way to register a stop call back as well. The new API introduced in this commit looks like this: ``` this.request('process:register', 'webserver', { launchFn: (callback) => { this.server.start(callback) }, stopFn: (callback) => this.server.stop(callback) } }); // and then this.request('process:launch', 'webserver', (err, message, port) => { // server started }); this.request('process:stop', 'webserver', err => { // server stopped }); ``` Notice that `process:register` works exactly the same way as before as well. Another thing to notice is that all parameters emitted by the underlying process are propagated to the outside caller, which is why `err`, `message` and `port` are available inside the launch callback.
2018-10-11 12:46:57 +00:00
name: name,
state: ProcessState.Unstarted,
cb: launchFn || cb,
stopFn: stopFn || function noop () {}
2018-07-26 16:37:33 +00:00
};
});
self.events.setCommandHandler('processes:launch', (name, cb) => {
feat(core/processManager): introduce `processes:stop` handlers So far, `ProcessManager` was able to only register a `process:launch` handler. There was no way to tell `ProcessManager` how to stop processes. This hasn't been a problem so far as most of the service processes can be started without the usage of the `ProcessManager`, but turns out to be necessary if we want Embark UI to be able to pick up running services. A good example is the webserver process, which until now bypasses the `ProcessManager` all together. The webserver sets up two event handlers to start and stop it respectively: ``` this.events.setCommandHandler('start-webserver', () => this.server.start()); this.events.setCommandHandler('stop-webserver', () => this.server.stop()); ``` In the future, this should happen through the `ProcessManager` instead, so the webserver process can be picked up by Embark UI, like this: ``` this.request('process:register', 'webserver', () => { this.server.start(); }); // and then this.request('process:launch', 'webserver', () => { // server started }); ``` Notice that the given callback to registering a process is actually the function that gets called to launch the process. Having that in mind, and considering that we also need a way to stop the process through `ProcessManager, so we don't introduce a regression, we need a way to register a stop call back as well. The new API introduced in this commit looks like this: ``` this.request('process:register', 'webserver', { launchFn: (callback) => { this.server.start(callback) }, stopFn: (callback) => this.server.stop(callback) } }); // and then this.request('process:launch', 'webserver', (err, message, port) => { // server started }); this.request('process:stop', 'webserver', err => { // server stopped }); ``` Notice that `process:register` works exactly the same way as before as well. Another thing to notice is that all parameters emitted by the underlying process are propagated to the outside caller, which is why `err`, `message` and `port` are available inside the launch callback.
2018-10-11 12:46:57 +00:00
cb = cb || function noop() {};
let process = self.processes[name];
feat(core/processManager): introduce `processes:stop` handlers So far, `ProcessManager` was able to only register a `process:launch` handler. There was no way to tell `ProcessManager` how to stop processes. This hasn't been a problem so far as most of the service processes can be started without the usage of the `ProcessManager`, but turns out to be necessary if we want Embark UI to be able to pick up running services. A good example is the webserver process, which until now bypasses the `ProcessManager` all together. The webserver sets up two event handlers to start and stop it respectively: ``` this.events.setCommandHandler('start-webserver', () => this.server.start()); this.events.setCommandHandler('stop-webserver', () => this.server.stop()); ``` In the future, this should happen through the `ProcessManager` instead, so the webserver process can be picked up by Embark UI, like this: ``` this.request('process:register', 'webserver', () => { this.server.start(); }); // and then this.request('process:launch', 'webserver', () => { // server started }); ``` Notice that the given callback to registering a process is actually the function that gets called to launch the process. Having that in mind, and considering that we also need a way to stop the process through `ProcessManager, so we don't introduce a regression, we need a way to register a stop call back as well. The new API introduced in this commit looks like this: ``` this.request('process:register', 'webserver', { launchFn: (callback) => { this.server.start(callback) }, stopFn: (callback) => this.server.stop(callback) } }); // and then this.request('process:launch', 'webserver', (err, message, port) => { // server started }); this.request('process:stop', 'webserver', err => { // server stopped }); ``` Notice that `process:register` works exactly the same way as before as well. Another thing to notice is that all parameters emitted by the underlying process are propagated to the outside caller, which is why `err`, `message` and `port` are available inside the launch callback.
2018-10-11 12:46:57 +00:00
if (process.state !== ProcessState.Unstarted) {
return cb();
}
feat(core/processManager): introduce `processes:stop` handlers So far, `ProcessManager` was able to only register a `process:launch` handler. There was no way to tell `ProcessManager` how to stop processes. This hasn't been a problem so far as most of the service processes can be started without the usage of the `ProcessManager`, but turns out to be necessary if we want Embark UI to be able to pick up running services. A good example is the webserver process, which until now bypasses the `ProcessManager` all together. The webserver sets up two event handlers to start and stop it respectively: ``` this.events.setCommandHandler('start-webserver', () => this.server.start()); this.events.setCommandHandler('stop-webserver', () => this.server.stop()); ``` In the future, this should happen through the `ProcessManager` instead, so the webserver process can be picked up by Embark UI, like this: ``` this.request('process:register', 'webserver', () => { this.server.start(); }); // and then this.request('process:launch', 'webserver', () => { // server started }); ``` Notice that the given callback to registering a process is actually the function that gets called to launch the process. Having that in mind, and considering that we also need a way to stop the process through `ProcessManager, so we don't introduce a regression, we need a way to register a stop call back as well. The new API introduced in this commit looks like this: ``` this.request('process:register', 'webserver', { launchFn: (callback) => { this.server.start(callback) }, stopFn: (callback) => this.server.stop(callback) } }); // and then this.request('process:launch', 'webserver', (err, message, port) => { // server started }); this.request('process:stop', 'webserver', err => { // server stopped }); ``` Notice that `process:register` works exactly the same way as before as well. Another thing to notice is that all parameters emitted by the underlying process are propagated to the outside caller, which is why `err`, `message` and `port` are available inside the launch callback.
2018-10-11 12:46:57 +00:00
process.state = ProcessState.Starting;
2018-07-26 16:37:33 +00:00
process.cb.apply(process.cb, [
feat(core/processManager): introduce `processes:stop` handlers So far, `ProcessManager` was able to only register a `process:launch` handler. There was no way to tell `ProcessManager` how to stop processes. This hasn't been a problem so far as most of the service processes can be started without the usage of the `ProcessManager`, but turns out to be necessary if we want Embark UI to be able to pick up running services. A good example is the webserver process, which until now bypasses the `ProcessManager` all together. The webserver sets up two event handlers to start and stop it respectively: ``` this.events.setCommandHandler('start-webserver', () => this.server.start()); this.events.setCommandHandler('stop-webserver', () => this.server.stop()); ``` In the future, this should happen through the `ProcessManager` instead, so the webserver process can be picked up by Embark UI, like this: ``` this.request('process:register', 'webserver', () => { this.server.start(); }); // and then this.request('process:launch', 'webserver', () => { // server started }); ``` Notice that the given callback to registering a process is actually the function that gets called to launch the process. Having that in mind, and considering that we also need a way to stop the process through `ProcessManager, so we don't introduce a regression, we need a way to register a stop call back as well. The new API introduced in this commit looks like this: ``` this.request('process:register', 'webserver', { launchFn: (callback) => { this.server.start(callback) }, stopFn: (callback) => this.server.stop(callback) } }); // and then this.request('process:launch', 'webserver', (err, message, port) => { // server started }); this.request('process:stop', 'webserver', err => { // server stopped }); ``` Notice that `process:register` works exactly the same way as before as well. Another thing to notice is that all parameters emitted by the underlying process are propagated to the outside caller, which is why `err`, `message` and `port` are available inside the launch callback.
2018-10-11 12:46:57 +00:00
(...args) => {
process.state = ProcessState.Running;
cb.apply(cb, args);
}
]);
});
self.events.setCommandHandler('processes:stop', (name, cb) => {
let process = self.processes[name];
cb = cb || function noop() {};
if (process.state !== ProcessState.Running) {
return cb();
}
process.state = ProcessState.Stopping;
process.stopFn.apply(process.stopFn, [
(...args) => {
process.state = ProcessState.Unstarted;
cb.apply(cb, args);
2018-07-26 16:37:33 +00:00
}
]);
});
}
}
module.exports = ProcessManager;