pandora
Version:
A powerful and lightweight application manager for Node.js applications powered by TypeScript.
172 lines • 7.07 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
require('source-map-support').install();
const program = require("commander");
const const_1 = require("../const");
const WorkerContext_1 = require("./WorkerContext");
const ProcfileReconciler_1 = require("./ProcfileReconciler");
const assert = require("assert");
const pandora_env_1 = require("pandora-env");
const LoggerBroker_1 = require("../universal/LoggerBroker");
const MonitorManager_1 = require("../monitor/MonitorManager");
/**
* class WorkerProcessBootstrap
* Bootstrap a worker process, handing all phases of an application stating
*/
class WorkerProcessBootstrap {
/**
* @param {string} entry - where is the entry file of this process of the application. that can be null,
* use the ProcfileReconciler to start if that be null.
* @param {ProcessRepresentation} processRepresentation - ProcessRepresentation object
*/
constructor(entry, processRepresentation) {
this.entry = entry;
this.processRepresentation = processRepresentation;
this.procfileReconciler = new ProcfileReconciler_1.ProcfileReconciler(processRepresentation);
this.context = new WorkerContext_1.WorkerContext(processRepresentation);
}
/**
* Start process
* 1. use the ProcfileReconciler to start if this.entry is not given
* 2. use the this.entry to start if this.entry is given
* @return {Promise<void>}
*/
start() {
return __awaiter(this, void 0, void 0, function* () {
if (this.entry) {
yield this.startByEntry();
return;
}
yield this.startByProcfile();
});
}
stop() {
return __awaiter(this, void 0, void 0, function* () {
if (this.context) {
yield this.context.stop();
}
});
}
/**
* Use procfile.js to start
* @returns {Promise<void>}
*/
startByProcfile() {
return __awaiter(this, void 0, void 0, function* () {
const { mode } = this.processRepresentation;
if ('procfile.js' === mode) {
// Beginning discover the process structure by ProcfileReconciler if mode be procfile.js
this.procfileReconciler.discover();
}
else {
throw new Error(`Unknown mode ${mode}`);
}
if (!pandora_env_1.EnvironmentUtil.getInstance().isReady()) {
// Handing the environment object injecting
const Environment = this.procfileReconciler.getEnvironment();
const environment = new Environment({
appDir: this.processRepresentation.appDir,
appName: this.processRepresentation.appName,
processName: this.processRepresentation.processName,
pandoraLogsDir: LoggerBroker_1.getPandoraLogsDir()
});
pandora_env_1.EnvironmentUtil.getInstance().setCurrentEnvironment(environment);
}
// To start worker process monitoring
MonitorManager_1.MonitorManager.injectProcessMonitor();
// Handing the services injecting
const servicesByCurrentCategory = this.procfileReconciler.getServicesByCategory(this.processRepresentation.processName);
this.context.bindService(servicesByCurrentCategory);
// To start process by WorkerContext
yield this.context.start();
});
}
/**
* use this.entry to start
* @returns {Promise<any>}
*/
startByEntry() {
return __awaiter(this, void 0, void 0, function* () {
const entryMod = require(this.entry);
const entryFn = 'function' === typeof entryMod ? entryMod : entryMod.default;
assert('function' === typeof entryFn, 'The entry should export a function, during loading ' + this.entry);
return yield new Promise((resolve, reject) => {
entryFn(Object.assign({}, this.processRepresentation), (err) => {
if (err) {
return reject(err);
}
resolve();
});
});
});
}
/**
* A static method to handing the CLI
*/
static cmd() {
program
.option('--entry [entry]')
.option('--params [params]')
.parse(process.argv);
const entry = program.entry;
let options;
try {
options = JSON.parse(program.params);
assert(options.appName, 'appName required by WorkerProcessBootstrap');
assert(options.appDir, 'appDir required by WorkerProcessBootstrap');
assert(options.processName, 'processName required by WorkerProcessBootstrap');
}
catch (err) {
err.message = `invalid options "${program.params}", ${err.message}`;
LoggerBroker_1.consoleLogger.error(err);
if (process.send) {
process.send({ action: const_1.ERROR, error: err });
}
return;
}
const workerBootstrap = new WorkerProcessBootstrap(entry, options);
workerBootstrap.start().then(() => {
process.on('message', (message) => {
if (message.action === const_1.SHUTDOWN) {
workerBootstrap.stop().then(() => {
if (process.send) {
process.send({ action: const_1.FINISH_SHUTDOWN });
}
});
}
});
if (process.send) {
process.send({ action: const_1.READY });
}
}).catch((err) => {
LoggerBroker_1.consoleLogger.error(err);
LoggerBroker_1.consoleLogger.error('an error occurred during the start of WorkerProcessBootstrap.');
if (process.send) {
process.send({ action: const_1.ERROR, error: err });
}
});
}
}
exports.WorkerProcessBootstrap = WorkerProcessBootstrap;
let cmdDid = false;
function cmd() {
if (cmdDid) {
return;
}
cmdDid = true;
WorkerProcessBootstrap.cmd();
}
exports.cmd = cmd;
// Handing CLI if this module be the main module
if (require.main === module) {
cmd();
}
//# sourceMappingURL=WorkerProcessBootstrap.js.map