querysub 0.210.0 → 0.212.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -51,20 +51,21 @@ const getTmuxPrefix = lazy(() => {
|
|
|
51
51
|
}
|
|
52
52
|
return "";
|
|
53
53
|
});
|
|
54
|
-
function textTableLineToObj(text: string): Record<string, string> {
|
|
54
|
+
function textTableLineToObj(text: string): Record<string, string>[] {
|
|
55
55
|
/*
|
|
56
56
|
PID PPID PGID WINPID TTY UID STIME COMMAND
|
|
57
57
|
1312 1284 1312 56996 pty2 197609 09:24:47 /usr/bin/bash
|
|
58
|
+
1313 1284 1313 56997 pty3 197609 09:24:48 /usr/bin/vim
|
|
58
59
|
=>
|
|
59
|
-
{ PID: "1312", PPID: "1284", ...}
|
|
60
|
+
[{ PID: "1312", PPID: "1284", ...}, { PID: "1313", PPID: "1284", ...}]
|
|
60
61
|
*/
|
|
61
62
|
let lines = text.trim().split("\n").filter(line => line.trim().length > 0);
|
|
62
63
|
if (lines.length < 2) {
|
|
63
|
-
return
|
|
64
|
+
return [];
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
let headerLine = lines[0];
|
|
67
|
-
let
|
|
68
|
+
let dataLines = lines.slice(1);
|
|
68
69
|
|
|
69
70
|
// Parse column positions from header
|
|
70
71
|
let columns: { name: string; start: number; end: number }[] = [];
|
|
@@ -83,43 +84,57 @@ function textTableLineToObj(text: string): Record<string, string> {
|
|
|
83
84
|
currentPos = start + word.length;
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
// Extract values from data
|
|
87
|
-
let
|
|
88
|
-
for (let
|
|
89
|
-
let
|
|
90
|
-
|
|
87
|
+
// Extract values from all data lines
|
|
88
|
+
let results: Record<string, string>[] = [];
|
|
89
|
+
for (let dataLine of dataLines) {
|
|
90
|
+
let result: Record<string, string> = {};
|
|
91
|
+
for (let column of columns) {
|
|
92
|
+
let value = dataLine.substring(column.start, column.end).trim();
|
|
93
|
+
result[column.name] = value;
|
|
94
|
+
}
|
|
95
|
+
results.push(result);
|
|
91
96
|
}
|
|
92
97
|
|
|
93
|
-
return
|
|
98
|
+
return results;
|
|
94
99
|
}
|
|
95
|
-
async function
|
|
100
|
+
async function getLinuxProcessInfo(pid: string) {
|
|
96
101
|
try {
|
|
97
|
-
let
|
|
98
|
-
let
|
|
102
|
+
let extraArgs = os.platform() !== "win32" && " -o ppid,cmd" || "";
|
|
103
|
+
let psInfo = await runPromise(`ps -p ${pid}${extraArgs}`);
|
|
104
|
+
let results = textTableLineToObj(psInfo);
|
|
105
|
+
let obj = results[0] as { PPID: string; CMD: string };
|
|
99
106
|
return obj;
|
|
100
107
|
} catch (e: any) {
|
|
101
108
|
console.warn(`Error getting tmux process info for ${pid}: ${e.stack}`);
|
|
102
109
|
return undefined;
|
|
103
110
|
}
|
|
104
111
|
}
|
|
105
|
-
async function
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
let
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
const getLinuxChildPids = measureWrap(async function getLinuxChildPids(pid: string): Promise<{ PID: string; PPID: string; CMD: string }[]> {
|
|
113
|
+
let prefix = getTmuxPrefix();
|
|
114
|
+
if (os.platform() === "win32") {
|
|
115
|
+
let table = await runPromise(`${prefix}ps`);
|
|
116
|
+
let obj = textTableLineToObj(table) as { PID: string; PPID: string; CMD: string }[];
|
|
117
|
+
return obj.filter(x => x.PPID === pid);
|
|
118
|
+
} else {
|
|
119
|
+
let table = await runPromise(`ps -eo pid,ppid,cmd`);
|
|
120
|
+
let obj = textTableLineToObj(table) as { PPID: string; PID: string; CMD: string }[];
|
|
121
|
+
return obj.filter(x => x.PPID === pid);
|
|
113
122
|
}
|
|
114
|
-
}
|
|
123
|
+
});
|
|
115
124
|
const isScreenRunningProcess = measureWrap(async function isScreenRunningProcess(pid: string): Promise<boolean> {
|
|
116
125
|
try {
|
|
117
|
-
let
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
126
|
+
let childPids = await getLinuxChildPids(pid);
|
|
127
|
+
let bashPid = childPids.find(x => x.CMD.includes("bash"));
|
|
128
|
+
if (!bashPid) {
|
|
129
|
+
console.error(`Screen pid ${pid} isn't even running bash? What? We can't check if it's running the process or not, so returning true, which disables crash detection...`);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
let bashChildPids = await getLinuxChildPids(bashPid.PID);
|
|
133
|
+
for (let childPid of bashChildPids) {
|
|
134
|
+
console.log(`Screen pid ${pid} is running ${childPid.CMD}`);
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
123
138
|
} catch (e: any) {
|
|
124
139
|
console.warn(`Error checking if screen is running for ${pid}: ${e.stack}`);
|
|
125
140
|
return false;
|
|
@@ -128,9 +143,11 @@ const isScreenRunningProcess = measureWrap(async function isScreenRunningProcess
|
|
|
128
143
|
const getScreenState = measureWrap(async function getScreenState(): Promise<{
|
|
129
144
|
screenName: string;
|
|
130
145
|
isProcessRunning: boolean;
|
|
146
|
+
pid: string;
|
|
131
147
|
}[]> {
|
|
132
148
|
const prefix = getTmuxPrefix();
|
|
133
149
|
const delimit = "::::";
|
|
150
|
+
// tmux list-panes -a -F "#{session_name}::::#{pane_pid}"
|
|
134
151
|
let screenList = (await runPromise(`${prefix}tmux list-panes -a -F "#{session_name}${delimit}#{pane_pid}"`))
|
|
135
152
|
.split("\n")
|
|
136
153
|
.filter(x => x.includes(delimit))
|
|
@@ -251,7 +268,12 @@ const resyncServices = runInSerial(measureWrap(async function resyncServices() {
|
|
|
251
268
|
command: config.parameters.command,
|
|
252
269
|
});
|
|
253
270
|
await delay(2000);
|
|
254
|
-
let
|
|
271
|
+
let newScreens = await getScreenState();
|
|
272
|
+
let foundScreen = newScreens.find(x => x.screenName === screenName);
|
|
273
|
+
if (!foundScreen) {
|
|
274
|
+
console.error(`Just created screen ${screenName}, but it's not in the list of screens!`);
|
|
275
|
+
}
|
|
276
|
+
let isRunning = foundScreen && await isScreenRunningProcess(foundScreen.pid);
|
|
255
277
|
if (!isRunning) {
|
|
256
278
|
let prefix = getTmuxPrefix();
|
|
257
279
|
let logs = await runPromise(`${prefix}tmux capture-pane -t ${screenName} -p`);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import child_process from "child_process";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import { red } from "socket-function/src/formatting/logColors";
|
|
3
|
+
import { blue, red } from "socket-function/src/formatting/logColors";
|
|
4
4
|
|
|
5
5
|
export const runAsync = runPromise;
|
|
6
6
|
export async function runPromise(command: string, config?: {
|
|
@@ -10,6 +10,7 @@ export async function runPromise(command: string, config?: {
|
|
|
10
10
|
nothrow?: boolean;
|
|
11
11
|
}) {
|
|
12
12
|
return new Promise<string>((resolve, reject) => {
|
|
13
|
+
console.log(">" + blue(command));
|
|
13
14
|
const childProc = child_process.spawn(command, {
|
|
14
15
|
shell: true,
|
|
15
16
|
cwd: config?.cwd,
|