forked from svrjs/svrjs
Added process.singleThreaded flag.
This commit is contained in:
parent
a3e4ee2328
commit
7a658613fe
2 changed files with 204 additions and 198 deletions
|
@ -1,6 +1,5 @@
|
||||||
const http = require("http");
|
const http = require("http");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const cluster = require("./utils/clusterBunShim.js"); // Cluster module with shim for Bun
|
|
||||||
//const generateErrorStack = require("./utils/generateErrorStack.js");
|
//const generateErrorStack = require("./utils/generateErrorStack.js");
|
||||||
const getOS = require("./utils/getOS.js");
|
const getOS = require("./utils/getOS.js");
|
||||||
const svrjsInfo = require("../svrjs.json");
|
const svrjsInfo = require("../svrjs.json");
|
||||||
|
@ -20,6 +19,10 @@ if (!fs.existsSync(__dirname + "/log")) fs.mkdirSync(__dirname + "/log");
|
||||||
if (!fs.existsSync(__dirname + "/mods")) fs.mkdirSync(__dirname + "/mods");
|
if (!fs.existsSync(__dirname + "/mods")) fs.mkdirSync(__dirname + "/mods");
|
||||||
if (!fs.existsSync(__dirname + "/temp")) fs.mkdirSync(__dirname + "/temp");
|
if (!fs.existsSync(__dirname + "/temp")) fs.mkdirSync(__dirname + "/temp");
|
||||||
|
|
||||||
|
// TODO: process.singleThreaded flag
|
||||||
|
process.singleThreaded = true;
|
||||||
|
const cluster = require("./utils/clusterBunShim.js"); // Cluster module with shim for Bun
|
||||||
|
|
||||||
const serverconsoleConstructor = require("./utils/serverconsole.js");
|
const serverconsoleConstructor = require("./utils/serverconsole.js");
|
||||||
|
|
||||||
let inspectorURL = undefined;
|
let inspectorURL = undefined;
|
||||||
|
|
|
@ -3,228 +3,231 @@ const os = require("os");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
|
||||||
let cluster = {};
|
let cluster = {};
|
||||||
try {
|
|
||||||
// Import cluster module
|
|
||||||
cluster = require("cluster");
|
|
||||||
} catch (err) {
|
|
||||||
// Clustering is not supported!
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cluster & IPC shim for Bun
|
if (!process.singleThreaded) {
|
||||||
|
try {
|
||||||
|
// Import cluster module
|
||||||
|
cluster = require("cluster");
|
||||||
|
} catch (err) {
|
||||||
|
// Clustering is not supported!
|
||||||
|
}
|
||||||
|
|
||||||
cluster.bunShim = function () {
|
// Cluster & IPC shim for Bun
|
||||||
cluster.isMaster = !process.env.NODE_UNIQUE_ID;
|
|
||||||
cluster.isPrimary = cluster.isMaster;
|
|
||||||
cluster.isWorker = !cluster.isMaster;
|
|
||||||
cluster.__shimmed__ = true;
|
|
||||||
|
|
||||||
if (cluster.isWorker) {
|
cluster.bunShim = function () {
|
||||||
// Shim the cluster.worker object for worker processes
|
cluster.isMaster = !process.env.NODE_UNIQUE_ID;
|
||||||
cluster.worker = {
|
cluster.isPrimary = cluster.isMaster;
|
||||||
id: parseInt(process.env.NODE_UNIQUE_ID),
|
cluster.isWorker = !cluster.isMaster;
|
||||||
process: process,
|
cluster.__shimmed__ = true;
|
||||||
isDead: function () {
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
send: function (message, b, c, d) {
|
|
||||||
process.send(message, b, c, d);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!process.send) {
|
if (cluster.isWorker) {
|
||||||
// Shim the process.send function for worker processes
|
// Shim the cluster.worker object for worker processes
|
||||||
|
cluster.worker = {
|
||||||
|
id: parseInt(process.env.NODE_UNIQUE_ID),
|
||||||
|
process: process,
|
||||||
|
isDead: function () {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
send: function (message, b, c, d) {
|
||||||
|
process.send(message, b, c, d);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// Create a fake IPC server to receive messages
|
if (!process.send) {
|
||||||
let fakeIPCServer = net.createServer(function (socket) {
|
// Shim the process.send function for worker processes
|
||||||
let receivedData = "";
|
|
||||||
|
|
||||||
socket.on("data", function (data) {
|
// Create a fake IPC server to receive messages
|
||||||
receivedData += data.toString();
|
let fakeIPCServer = net.createServer(function (socket) {
|
||||||
|
let receivedData = "";
|
||||||
|
|
||||||
|
socket.on("data", function (data) {
|
||||||
|
receivedData += data.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("end", function () {
|
||||||
|
process.emit("message", receivedData);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
fakeIPCServer.listen(
|
||||||
socket.on("end", function () {
|
|
||||||
process.emit("message", receivedData);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
fakeIPCServer.listen(
|
|
||||||
os.platform() === "win32"
|
|
||||||
? path.join(
|
|
||||||
"\\\\?\\pipe",
|
|
||||||
__dirname,
|
|
||||||
"temp/.W" + process.pid + ".ipc",
|
|
||||||
)
|
|
||||||
: __dirname + "/temp/.W" + process.pid + ".ipc",
|
|
||||||
);
|
|
||||||
|
|
||||||
process.send = function (message) {
|
|
||||||
// Create a fake IPC connection to send messages
|
|
||||||
let fakeIPCConnection = net.createConnection(
|
|
||||||
os.platform() === "win32"
|
os.platform() === "win32"
|
||||||
? path.join(
|
? path.join(
|
||||||
"\\\\?\\pipe",
|
"\\\\?\\pipe",
|
||||||
__dirname,
|
__dirname,
|
||||||
"temp/.P" + process.pid + ".ipc",
|
"temp/.W" + process.pid + ".ipc",
|
||||||
)
|
)
|
||||||
: __dirname + "/temp/.P" + process.pid + ".ipc",
|
: __dirname + "/temp/.W" + process.pid + ".ipc",
|
||||||
function () {
|
|
||||||
fakeIPCConnection.end(message);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
process.removeFakeIPC = function () {
|
process.send = function (message) {
|
||||||
// Close IPC server
|
// Create a fake IPC connection to send messages
|
||||||
process.send = function () {};
|
let fakeIPCConnection = net.createConnection(
|
||||||
fakeIPCServer.close();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Custom implementation for cluster.fork()
|
|
||||||
cluster._workersCounter = 1;
|
|
||||||
cluster.workers = {};
|
|
||||||
cluster.fork = function (env) {
|
|
||||||
const child_process = require("child_process");
|
|
||||||
let newEnvironment = Object.assign(env ? env : process.env);
|
|
||||||
newEnvironment.NODE_UNIQUE_ID = cluster._workersCounter;
|
|
||||||
let newArguments = Object.assign(process.argv);
|
|
||||||
let command = newArguments.shift();
|
|
||||||
let newWorker = child_process.spawn(command, newArguments, {
|
|
||||||
env: newEnvironment,
|
|
||||||
stdio: ["inherit", "inherit", "inherit", "ipc"],
|
|
||||||
});
|
|
||||||
|
|
||||||
newWorker.process = newWorker;
|
|
||||||
newWorker.isDead = function () {
|
|
||||||
return newWorker.exitCode !== null || newWorker.killed;
|
|
||||||
};
|
|
||||||
newWorker.id = newEnvironment.NODE_UNIQUE_ID;
|
|
||||||
|
|
||||||
function checkSendImplementation(worker) {
|
|
||||||
let sendImplemented = true;
|
|
||||||
|
|
||||||
if (
|
|
||||||
!(
|
|
||||||
process.versions &&
|
|
||||||
process.versions.bun &&
|
|
||||||
process.versions.bun[0] != "0"
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
if (!worker.send) {
|
|
||||||
sendImplemented = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let oldLog = console.log;
|
|
||||||
console.log = function (a, b, c, d, e, f) {
|
|
||||||
if (
|
|
||||||
a == "ChildProcess.prototype.send() - Sorry! Not implemented yet"
|
|
||||||
) {
|
|
||||||
throw new Error("NOT IMPLEMENTED");
|
|
||||||
} else {
|
|
||||||
oldLog(a, b, c, d, e, f);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
worker.send(undefined);
|
|
||||||
} catch (err) {
|
|
||||||
if (err.message === "NOT IMPLEMENTED") {
|
|
||||||
sendImplemented = false;
|
|
||||||
}
|
|
||||||
console.log(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log = oldLog;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sendImplemented;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!checkSendImplementation(newWorker)) {
|
|
||||||
// Create a fake IPC server for worker process to receive messages
|
|
||||||
let fakeWorkerIPCServer = net.createServer(function (socket) {
|
|
||||||
let receivedData = "";
|
|
||||||
|
|
||||||
socket.on("data", function (data) {
|
|
||||||
receivedData += data.toString();
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on("end", function () {
|
|
||||||
newWorker.emit("message", receivedData);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
fakeWorkerIPCServer.listen(
|
|
||||||
os.platform() === "win32"
|
|
||||||
? path.join(
|
|
||||||
"\\\\?\\pipe",
|
|
||||||
__dirname,
|
|
||||||
"temp/.P" + newWorker.process.pid + ".ipc",
|
|
||||||
)
|
|
||||||
: __dirname + "/temp/.P" + newWorker.process.pid + ".ipc",
|
|
||||||
);
|
|
||||||
|
|
||||||
// Cleanup when worker process exits
|
|
||||||
newWorker.on("exit", function () {
|
|
||||||
fakeWorkerIPCServer.close();
|
|
||||||
delete cluster.workers[newWorker.id];
|
|
||||||
});
|
|
||||||
|
|
||||||
newWorker.send = function (
|
|
||||||
message,
|
|
||||||
fakeParam2,
|
|
||||||
fakeParam3,
|
|
||||||
fakeParam4,
|
|
||||||
tries,
|
|
||||||
) {
|
|
||||||
if (!tries) tries = 0;
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Create a fake IPC connection to send messages to worker process
|
|
||||||
let fakeWorkerIPCConnection = net.createConnection(
|
|
||||||
os.platform() === "win32"
|
os.platform() === "win32"
|
||||||
? path.join(
|
? path.join(
|
||||||
"\\\\?\\pipe",
|
"\\\\?\\pipe",
|
||||||
__dirname,
|
__dirname,
|
||||||
"temp/.W" + newWorker.process.pid + ".ipc",
|
"temp/.P" + process.pid + ".ipc",
|
||||||
)
|
)
|
||||||
: __dirname + "/temp/.W" + newWorker.process.pid + ".ipc",
|
: __dirname + "/temp/.P" + process.pid + ".ipc",
|
||||||
function () {
|
function () {
|
||||||
fakeWorkerIPCConnection.end(message);
|
fakeIPCConnection.end(message);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (err) {
|
};
|
||||||
if (tries > 50) throw err;
|
|
||||||
newWorker.send(
|
process.removeFakeIPC = function () {
|
||||||
message,
|
// Close IPC server
|
||||||
fakeParam2,
|
process.send = function () {};
|
||||||
fakeParam3,
|
fakeIPCServer.close();
|
||||||
fakeParam4,
|
};
|
||||||
tries + 1,
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
newWorker.on("exit", function () {
|
|
||||||
delete cluster.workers[newWorker.id];
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cluster.workers[newWorker.id] = newWorker;
|
// Custom implementation for cluster.fork()
|
||||||
cluster._workersCounter++;
|
cluster._workersCounter = 1;
|
||||||
return newWorker;
|
cluster.workers = {};
|
||||||
};
|
cluster.fork = function (env) {
|
||||||
};
|
const child_process = require("child_process");
|
||||||
|
let newEnvironment = Object.assign(env ? env : process.env);
|
||||||
|
newEnvironment.NODE_UNIQUE_ID = cluster._workersCounter;
|
||||||
|
let newArguments = Object.assign(process.argv);
|
||||||
|
let command = newArguments.shift();
|
||||||
|
let newWorker = child_process.spawn(command, newArguments, {
|
||||||
|
env: newEnvironment,
|
||||||
|
stdio: ["inherit", "inherit", "inherit", "ipc"],
|
||||||
|
});
|
||||||
|
|
||||||
if (
|
newWorker.process = newWorker;
|
||||||
process.isBun &&
|
newWorker.isDead = function () {
|
||||||
(cluster.isMaster === undefined ||
|
return newWorker.exitCode !== null || newWorker.killed;
|
||||||
(cluster.isMaster && process.env.NODE_UNIQUE_ID))
|
};
|
||||||
) {
|
newWorker.id = newEnvironment.NODE_UNIQUE_ID;
|
||||||
cluster.bunShim();
|
|
||||||
|
function checkSendImplementation(worker) {
|
||||||
|
let sendImplemented = true;
|
||||||
|
|
||||||
|
if (
|
||||||
|
!(
|
||||||
|
process.versions &&
|
||||||
|
process.versions.bun &&
|
||||||
|
process.versions.bun[0] != "0"
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (!worker.send) {
|
||||||
|
sendImplemented = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let oldLog = console.log;
|
||||||
|
console.log = function (a, b, c, d, e, f) {
|
||||||
|
if (
|
||||||
|
a == "ChildProcess.prototype.send() - Sorry! Not implemented yet"
|
||||||
|
) {
|
||||||
|
throw new Error("NOT IMPLEMENTED");
|
||||||
|
} else {
|
||||||
|
oldLog(a, b, c, d, e, f);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
worker.send(undefined);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.message === "NOT IMPLEMENTED") {
|
||||||
|
sendImplemented = false;
|
||||||
|
}
|
||||||
|
console.log(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log = oldLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sendImplemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkSendImplementation(newWorker)) {
|
||||||
|
// Create a fake IPC server for worker process to receive messages
|
||||||
|
let fakeWorkerIPCServer = net.createServer(function (socket) {
|
||||||
|
let receivedData = "";
|
||||||
|
|
||||||
|
socket.on("data", function (data) {
|
||||||
|
receivedData += data.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on("end", function () {
|
||||||
|
newWorker.emit("message", receivedData);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
fakeWorkerIPCServer.listen(
|
||||||
|
os.platform() === "win32"
|
||||||
|
? path.join(
|
||||||
|
"\\\\?\\pipe",
|
||||||
|
__dirname,
|
||||||
|
"temp/.P" + newWorker.process.pid + ".ipc",
|
||||||
|
)
|
||||||
|
: __dirname + "/temp/.P" + newWorker.process.pid + ".ipc",
|
||||||
|
);
|
||||||
|
|
||||||
|
// Cleanup when worker process exits
|
||||||
|
newWorker.on("exit", function () {
|
||||||
|
fakeWorkerIPCServer.close();
|
||||||
|
delete cluster.workers[newWorker.id];
|
||||||
|
});
|
||||||
|
|
||||||
|
newWorker.send = function (
|
||||||
|
message,
|
||||||
|
fakeParam2,
|
||||||
|
fakeParam3,
|
||||||
|
fakeParam4,
|
||||||
|
tries,
|
||||||
|
) {
|
||||||
|
if (!tries) tries = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Create a fake IPC connection to send messages to worker process
|
||||||
|
let fakeWorkerIPCConnection = net.createConnection(
|
||||||
|
os.platform() === "win32"
|
||||||
|
? path.join(
|
||||||
|
"\\\\?\\pipe",
|
||||||
|
__dirname,
|
||||||
|
"temp/.W" + newWorker.process.pid + ".ipc",
|
||||||
|
)
|
||||||
|
: __dirname + "/temp/.W" + newWorker.process.pid + ".ipc",
|
||||||
|
function () {
|
||||||
|
fakeWorkerIPCConnection.end(message);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
if (tries > 50) throw err;
|
||||||
|
newWorker.send(
|
||||||
|
message,
|
||||||
|
fakeParam2,
|
||||||
|
fakeParam3,
|
||||||
|
fakeParam4,
|
||||||
|
tries + 1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
newWorker.on("exit", function () {
|
||||||
|
delete cluster.workers[newWorker.id];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster.workers[newWorker.id] = newWorker;
|
||||||
|
cluster._workersCounter++;
|
||||||
|
return newWorker;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (
|
||||||
|
process.isBun &&
|
||||||
|
(cluster.isMaster === undefined ||
|
||||||
|
(cluster.isMaster && process.env.NODE_UNIQUE_ID))
|
||||||
|
) {
|
||||||
|
cluster.bunShim();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shim cluster.isPrimary field
|
||||||
|
if (cluster.isPrimary === undefined && cluster.isMaster !== undefined)
|
||||||
|
cluster.isPrimary = cluster.isMaster;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shim cluster.isPrimary field
|
|
||||||
if (cluster.isPrimary === undefined && cluster.isMaster !== undefined)
|
|
||||||
cluster.isPrimary = cluster.isMaster;
|
|
||||||
|
|
||||||
module.exports = cluster;
|
module.exports = cluster;
|
||||||
|
|
Reference in a new issue