Server : Apache System : Linux 145.162.205.92.host.secureserver.net 5.14.0-611.45.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Apr 1 05:56:53 EDT 2026 x86_64 User : tradze ( 1001) PHP Version : 8.1.34 Disable Function : NONE Directory : /home/tradze/public_html/node-socket/node_modules/forever/lib/forever/ |
const events = require('events');
const fs = require('fs');
const path = require('path');
const nssocket = require('nssocket');
const util = require('util');
const utils = require('../util/utils');
const forever = require(path.resolve(__dirname, '..', 'forever'));
const Worker = exports.Worker = function (options) {
events.EventEmitter.call(this);
options = options || {};
this.monitor = options.monitor;
this.sockPath = options.sockPath || forever.config.get('sockPath');
this.exitOnStop = options.exitOnStop === true;
this._socket = null;
};
util.inherits(Worker, events.EventEmitter);
Worker.prototype.start = function (callback) {
var self = this,
err;
if (this._socket) {
err = new Error("Can't start already started worker");
if (callback) {
return callback(err);
}
throw err;
}
//
// Defines a simple `nssocket` protocol for communication
// with a parent process.
//
function workerProtocol(socket) {
socket.on('error', function() {
socket.destroy();
});
socket.data(['ping'], function () {
socket.send(['pong']);
});
socket.data(['data'], function () {
socket.send(['data'], self.monitor.data);
});
socket.data(['spawn'], function (data) {
if (!data.script) {
return socket.send(['spawn', 'error'], { error: new Error('No script given') });
}
if (self.monitor) {
return socket.send(['spawn', 'error'], { error: new Error("Already running") });
}
var monitor = new (forever.Monitor)(data.script, data.args);
monitor.start();
monitor.on('start', function () {
socket.send(['spawn', 'start'], monitor.data);
});
});
socket.data(['stop'], function () {
function onStop(err) {
var args = [];
if (err && err instanceof Error) {
args.push(['stop', 'error'], { message: err.message, stack: err.stack });
self.monitor.removeListener('stop', onStop);
}
else {
args.push(['stop', 'ok']);
self.monitor.removeListener('error', onStop);
}
socket.send.apply(socket, args);
if (self.exitOnStop) {
process.exit();
}
}
self.monitor.once('stop', onStop);
self.monitor.once('error', onStop);
if (process.platform === 'win32') {
//
// On Windows, delete the 'symbolic' sock file. This
// file is used for exploration during `forever list`
// as a mapping to the `\\.pipe\\*` "files" that can't
// be enumerated because ... Windows.
//
fs.unlinkSync(self._sockFile);
}
self.monitor.stop();
});
socket.data(['restart'], function () {
self.monitor.once('restart', function () {
socket.send(['restart', 'ok']);
});
self.monitor.restart();
});
}
function findAndStart() {
self._socket = nssocket.createServer(workerProtocol);
self._socket.on('listening', function () {
//
// `listening` listener doesn't take error as the first parameter
//
self.emit('start');
if (callback) {
callback(null, self._sockFile);
}
});
self._socket.on('error', function (err) {
if (err.code === 'EADDRINUSE') {
return findAndStart();
}
else if (callback) {
callback(err);
}
});
//
// Create a unique socket file based on the current microtime.
//
var sock = self._sockFile = path.join(self.sockPath, [
'worker',
new Date().getTime() + utils.randomString(3),
'sock'
].join('.'));
if (process.platform === 'win32') {
//
// Create 'symbolic' file on the system, so it can be later
// found via "forever list" since the `\\.pipe\\*` "files" can't
// be enumerated because ... Windows.
//
fs.openSync(sock, 'w');
//
// It needs the prefix, otherwise EACCESS error happens on Windows
// (no .sock extension, only named pipes with .pipe prefixes)
//
sock = '\\\\.\\pipe\\' + sock;
}
self._socket.listen(sock);
}
//
// Attempt to start the server the first time
//
findAndStart();
return this;
};