mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-22 01:03:01 +02:00
NETSCRIPT: Greatly speed up script launching, and remove the limitation unique args per script (#440)
* Remove the limitation unique args per script * Internal changes to how runningScripts are stored on the server, to make common usage faster.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Terminal } from "../../Terminal";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { findRunningScript } from "../../Script/ScriptHelpers";
|
||||
import { findRunningScripts } from "../../Script/ScriptHelpers";
|
||||
import { hasScriptExtension, validScriptExtensions } from "../../Paths/ScriptFilePath";
|
||||
|
||||
export function check(args: (string | number | boolean)[], server: BaseServer): void {
|
||||
@@ -16,8 +16,11 @@ export function check(args: (string | number | boolean)[], server: BaseServer):
|
||||
}
|
||||
|
||||
// Check that the script is running on this machine
|
||||
const runningScript = findRunningScript(scriptName, args.slice(1), server);
|
||||
if (runningScript == null) return Terminal.error(`No script named ${scriptName} is running on the server`);
|
||||
runningScript.displayLog();
|
||||
const runningScripts = findRunningScripts(scriptName, args.slice(1), server);
|
||||
if (runningScripts === null) {
|
||||
Terminal.error(`No script named ${scriptName} is running on the server`);
|
||||
return;
|
||||
}
|
||||
runningScripts.values().next().value.displayLog();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,50 @@
|
||||
import { Terminal } from "../../Terminal";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
||||
import { findRunningScripts } from "../../Script/ScriptHelpers";
|
||||
import { killWorkerScriptByPid } from "../../Netscript/killWorkerScript";
|
||||
import { hasScriptExtension } from "../../Paths/ScriptFilePath";
|
||||
|
||||
import type { BaseServer } from "../../Server/BaseServer";
|
||||
|
||||
export function kill(args: (string | number | boolean)[], server: BaseServer): void {
|
||||
if (args.length < 1) {
|
||||
return Terminal.error("Incorrect usage of kill command. Usage: kill [pid] or kill [scriptname] [arg1] [arg2]...");
|
||||
}
|
||||
if (typeof args[0] === "number") {
|
||||
const pid = args[0];
|
||||
if (killWorkerScript(pid)) return Terminal.print(`Killing script with PID ${pid}`);
|
||||
}
|
||||
// Shift args doesn't need to be sliced to check runningScript args
|
||||
const fileName = String(args.shift());
|
||||
const path = Terminal.getFilepath(fileName);
|
||||
if (!path) return Terminal.error(`Could not parse filename: ${fileName}`);
|
||||
if (!hasScriptExtension(path)) return Terminal.error(`${path} does not have a script file extension`);
|
||||
try {
|
||||
if (args.length < 1 || typeof args[0] === "boolean") {
|
||||
Terminal.error("Incorrect usage of kill command. Usage: kill [pid] or kill [scriptname] [arg1] [arg2]...");
|
||||
return;
|
||||
}
|
||||
|
||||
const runningScript = server.getRunningScript(path, args);
|
||||
if (runningScript == null) return Terminal.error("No such script is running. Nothing to kill");
|
||||
// Kill by PID
|
||||
if (typeof args[0] === "number") {
|
||||
const pid = args[0];
|
||||
const res = killWorkerScriptByPid(pid);
|
||||
if (res) {
|
||||
Terminal.print(`Killing script with PID ${pid}`);
|
||||
} else {
|
||||
Terminal.error(`Failed to kill script with PID ${pid}. No such script is running`);
|
||||
}
|
||||
|
||||
killWorkerScript(runningScript.pid);
|
||||
Terminal.print(`Killing ${path}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const path = Terminal.getFilepath(args[0]);
|
||||
if (!path) return Terminal.error(`Invalid filename: ${args[0]}`);
|
||||
if (!hasScriptExtension(path)) return Terminal.error(`Invalid file extension. Kill can only be used on scripts.`);
|
||||
const runningScripts = findRunningScripts(path, args.slice(1), server);
|
||||
if (runningScripts === null) {
|
||||
Terminal.error("No such script is running. Nothing to kill");
|
||||
return;
|
||||
}
|
||||
let killed = 0;
|
||||
for (const pid of runningScripts.keys()) {
|
||||
killed++;
|
||||
if (killed < 5) {
|
||||
Terminal.print(`Killing ${path} with pid ${pid}`);
|
||||
}
|
||||
killWorkerScriptByPid(pid);
|
||||
}
|
||||
if (killed >= 5) {
|
||||
Terminal.print(`... killed ${killed} instances total`);
|
||||
}
|
||||
} catch (e) {
|
||||
Terminal.error(e + "");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Terminal } from "../../Terminal";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { killWorkerScript } from "../../Netscript/killWorkerScript";
|
||||
import { WorkerScriptStartStopEventEmitter } from "../../Netscript/WorkerScriptStartStopEventEmitter";
|
||||
import { killWorkerScriptByPid } from "../../Netscript/killWorkerScript";
|
||||
|
||||
export function killall(_args: (string | number | boolean)[], server: BaseServer): void {
|
||||
Terminal.print("Killing all running scripts");
|
||||
for (const runningScript of server.runningScripts) killWorkerScript(runningScript.pid);
|
||||
WorkerScriptStartStopEventEmitter.emit();
|
||||
for (const byPid of server.runningScriptMap.values()) {
|
||||
for (const runningScript of byPid.values()) {
|
||||
killWorkerScriptByPid(runningScript.pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Terminal } from "../../Terminal";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { matchScriptPathUnanchored } from "../../utils/helpers/scriptKey";
|
||||
import * as libarg from "arg";
|
||||
|
||||
export function ps(args: (string | number | boolean)[], server: BaseServer): void {
|
||||
@@ -17,26 +18,15 @@ export function ps(args: (string | number | boolean)[], server: BaseServer): voi
|
||||
Terminal.error("Incorrect usage of ps command. Usage: ps [-g, --grep pattern]");
|
||||
return;
|
||||
}
|
||||
const pattern = flags["--grep"];
|
||||
if (pattern) {
|
||||
const re = new RegExp(pattern.toString());
|
||||
const matching = server.runningScripts.filter((x) => re.test(x.filename));
|
||||
for (let i = 0; i < matching.length; i++) {
|
||||
const rsObj = matching[i];
|
||||
let res = `(PID - ${rsObj.pid}) ${rsObj.filename}`;
|
||||
for (let j = 0; j < rsObj.args.length; ++j) {
|
||||
res += " " + rsObj.args[j].toString();
|
||||
}
|
||||
Terminal.print(res);
|
||||
}
|
||||
let pattern = flags["--grep"];
|
||||
if (!pattern) {
|
||||
pattern = ".*"; // Match anything
|
||||
}
|
||||
if (args.length === 0) {
|
||||
for (let i = 0; i < server.runningScripts.length; i++) {
|
||||
const rsObj = server.runningScripts[i];
|
||||
let res = `(PID - ${rsObj.pid}) ${rsObj.filename}`;
|
||||
for (let j = 0; j < rsObj.args.length; ++j) {
|
||||
res += " " + rsObj.args[j].toString();
|
||||
}
|
||||
const re = matchScriptPathUnanchored(pattern);
|
||||
for (const [k, byPid] of server.runningScriptMap) {
|
||||
if (!re.test(k)) continue;
|
||||
for (const rsObj of byPid.values()) {
|
||||
const res = `(PID - ${rsObj.pid}) ${rsObj.filename} ${rsObj.args.join(" ")}`;
|
||||
Terminal.print(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,11 +28,6 @@ export function runScript(path: ScriptFilePath, commandArgs: (string | number |
|
||||
// Todo: Switch out arg for something with typescript support
|
||||
const args = flags["_"] as ScriptArg[];
|
||||
|
||||
// Check if this script is already running
|
||||
if (server.getRunningScript(path, args)) {
|
||||
return Terminal.error("This script is already running with the same args.");
|
||||
}
|
||||
|
||||
const singleRamUsage = script.getRamUsage(server.scripts);
|
||||
if (!singleRamUsage) return Terminal.error("Error while calculating ram usage for this script.");
|
||||
|
||||
|
||||
@@ -1,66 +1,38 @@
|
||||
import { Terminal } from "../../Terminal";
|
||||
import { BaseServer } from "../../Server/BaseServer";
|
||||
import { findRunningScriptByPid } from "../../Script/ScriptHelpers";
|
||||
import { compareArrays } from "../../utils/helpers/compareArrays";
|
||||
import { findRunningScripts, findRunningScriptByPid } from "../../Script/ScriptHelpers";
|
||||
import { LogBoxEvents } from "../../ui/React/LogBoxManager";
|
||||
import { hasScriptExtension } from "../../Paths/ScriptFilePath";
|
||||
|
||||
export function tail(commandArray: (string | number | boolean)[], server: BaseServer): void {
|
||||
if (commandArray.length < 1) {
|
||||
return Terminal.error("Incorrect number of arguments. Usage: tail [script] [arg1] [arg2]...");
|
||||
}
|
||||
if (typeof commandArray[0] === "number") {
|
||||
const runningScript = findRunningScriptByPid(commandArray[0], server);
|
||||
if (!runningScript) return Terminal.error(`No script with PID ${commandArray[0]} is running on the server`);
|
||||
LogBoxEvents.emit(runningScript);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (commandArray.length < 1) {
|
||||
Terminal.error("Incorrect number of arguments. Usage: tail [script] [arg1] [arg2]...");
|
||||
} else if (typeof commandArray[0] === "string") {
|
||||
const [rawName, ...args] = commandArray;
|
||||
const path = Terminal.getFilepath(rawName);
|
||||
if (!path) return Terminal.error(`Invalid filename: ${rawName}`);
|
||||
if (!hasScriptExtension(path)) return Terminal.error(`Invalid file extension. Tail can only be used on scripts.`);
|
||||
|
||||
const path = Terminal.getFilepath(String(commandArray[0]));
|
||||
if (!path) return Terminal.error(`Invalid file path: ${commandArray[0]}`);
|
||||
if (!hasScriptExtension(path)) return Terminal.error(`Invalid file extension. Tail can only be used on scripts.`);
|
||||
const candidates = findRunningScripts(path, args, server);
|
||||
|
||||
// Get script arguments
|
||||
const args = [];
|
||||
for (let i = 1; i < commandArray.length; ++i) {
|
||||
args.push(commandArray[i]);
|
||||
}
|
||||
|
||||
// go over all the running scripts. If there's a perfect
|
||||
// match, use it!
|
||||
for (let i = 0; i < server.runningScripts.length; ++i) {
|
||||
if (server.runningScripts[i].filename === path && compareArrays(server.runningScripts[i].args, args)) {
|
||||
LogBoxEvents.emit(server.runningScripts[i]);
|
||||
return;
|
||||
// if there's no candidate then we just don't know.
|
||||
if (candidates === null) {
|
||||
Terminal.error(`No script named ${path} with args ${JSON.stringify(args)} is running on the server`);
|
||||
return;
|
||||
}
|
||||
// Just use the first one (if there are multiple with the same
|
||||
// arguments, they can't be distinguished except by pid).
|
||||
LogBoxEvents.emit(candidates.values().next().value);
|
||||
} else if (typeof commandArray[0] === "number") {
|
||||
const runningScript = findRunningScriptByPid(commandArray[0], server);
|
||||
if (runningScript == null) {
|
||||
Terminal.error(`No script with PID ${commandArray[0]} is running on the server`);
|
||||
return;
|
||||
}
|
||||
LogBoxEvents.emit(runningScript);
|
||||
}
|
||||
} catch (e) {
|
||||
Terminal.error(e + "");
|
||||
}
|
||||
|
||||
// Find all scripts that are potential candidates.
|
||||
const candidates = [];
|
||||
for (let i = 0; i < server.runningScripts.length; ++i) {
|
||||
// only scripts that have more arguments (equal arguments is already caught)
|
||||
if (server.runningScripts[i].args.length < args.length) continue;
|
||||
// make a smaller copy of the args.
|
||||
const args2 = server.runningScripts[i].args.slice(0, args.length);
|
||||
if (server.runningScripts[i].filename === path && compareArrays(args2, args)) {
|
||||
candidates.push(server.runningScripts[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// If there's only 1 possible choice, use that.
|
||||
if (candidates.length === 1) {
|
||||
LogBoxEvents.emit(candidates[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise lists all possible conflicting choices.
|
||||
if (candidates.length > 1) {
|
||||
Terminal.error("Found several potential candidates:");
|
||||
for (const candidate of candidates) Terminal.error(`${candidate.filename} ${candidate.args.join(" ")}`);
|
||||
Terminal.error("Script arguments need to be specified.");
|
||||
return;
|
||||
}
|
||||
|
||||
// if there's no candidate then we just don't know.
|
||||
Terminal.error(`No script named ${path} is running on the server`);
|
||||
}
|
||||
|
||||
@@ -26,29 +26,29 @@ export function top(args: (string | number | boolean)[], server: BaseServer): vo
|
||||
|
||||
Terminal.print(headers);
|
||||
|
||||
const currRunningScripts = server.runningScripts;
|
||||
const currRunningScripts = server.runningScriptMap;
|
||||
// Iterate through scripts on current server
|
||||
for (let i = 0; i < currRunningScripts.length; i++) {
|
||||
const script = currRunningScripts[i];
|
||||
for (const byPid of currRunningScripts.values()) {
|
||||
for (const script of byPid.values()) {
|
||||
// Calculate name padding
|
||||
const numSpacesScript = Math.max(0, scriptWidth - script.filename.length);
|
||||
const spacesScript = " ".repeat(numSpacesScript);
|
||||
|
||||
// Calculate name padding
|
||||
const numSpacesScript = Math.max(0, scriptWidth - script.filename.length);
|
||||
const spacesScript = " ".repeat(numSpacesScript);
|
||||
// Calculate PID padding
|
||||
const numSpacesPid = Math.max(0, pidWidth - (script.pid + "").length);
|
||||
const spacesPid = " ".repeat(numSpacesPid);
|
||||
|
||||
// Calculate PID padding
|
||||
const numSpacesPid = Math.max(0, pidWidth - (script.pid + "").length);
|
||||
const spacesPid = " ".repeat(numSpacesPid);
|
||||
// Calculate thread padding
|
||||
const numSpacesThread = Math.max(0, threadsWidth - (script.threads + "").length);
|
||||
const spacesThread = " ".repeat(numSpacesThread);
|
||||
|
||||
// Calculate thread padding
|
||||
const numSpacesThread = Math.max(0, threadsWidth - (script.threads + "").length);
|
||||
const spacesThread = " ".repeat(numSpacesThread);
|
||||
// Calculate and transform RAM usage
|
||||
const ramUsage = formatRam(script.ramUsage * script.threads);
|
||||
|
||||
// Calculate and transform RAM usage
|
||||
const ramUsage = formatRam(script.ramUsage * script.threads);
|
||||
|
||||
const entry = [script.filename, spacesScript, script.pid, spacesPid, script.threads, spacesThread, ramUsage].join(
|
||||
"",
|
||||
);
|
||||
Terminal.print(entry);
|
||||
const entry = [script.filename, spacesScript, script.pid, spacesPid, script.threads, spacesThread, ramUsage].join(
|
||||
"",
|
||||
);
|
||||
Terminal.print(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user