querysub 0.211.0 → 0.213.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
|
@@ -18,7 +18,7 @@ import os from "os";
|
|
|
18
18
|
import fs from "fs";
|
|
19
19
|
import { lazy } from "socket-function/src/caching";
|
|
20
20
|
import { setGitRef } from "../4-deploy/git";
|
|
21
|
-
import { blue, magenta } from "socket-function/src/formatting/logColors";
|
|
21
|
+
import { blue, green, magenta } from "socket-function/src/formatting/logColors";
|
|
22
22
|
import { shutdown } from "../diagnostics/periodic";
|
|
23
23
|
|
|
24
24
|
const getLiveMachineInfo = measureWrap(async function getLiveMachineInfo() {
|
|
@@ -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,55 +84,70 @@ 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... is running ${JSON.stringify(childPids)}`);
|
|
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;
|
|
126
141
|
}
|
|
127
142
|
});
|
|
128
|
-
const getScreenState = measureWrap(async function getScreenState(): Promise<{
|
|
143
|
+
const getScreenState = measureWrap(async function getScreenState(populateIsProcessRunning: boolean = true): Promise<{
|
|
129
144
|
screenName: string;
|
|
130
145
|
isProcessRunning: boolean;
|
|
131
146
|
pid: string;
|
|
132
147
|
}[]> {
|
|
133
148
|
const prefix = getTmuxPrefix();
|
|
134
149
|
const delimit = "::::";
|
|
150
|
+
// tmux list-panes -a -F "#{session_name}::::#{pane_pid}"
|
|
135
151
|
let screenList = (await runPromise(`${prefix}tmux list-panes -a -F "#{session_name}${delimit}#{pane_pid}"`))
|
|
136
152
|
.split("\n")
|
|
137
153
|
.filter(x => x.includes(delimit))
|
|
@@ -143,9 +159,11 @@ const getScreenState = measureWrap(async function getScreenState(): Promise<{
|
|
|
143
159
|
.filter(x => x.screenName.endsWith(SCREEN_SUFFIX))
|
|
144
160
|
;
|
|
145
161
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
if (populateIsProcessRunning) {
|
|
163
|
+
await Promise.all(screenList.map(async x => {
|
|
164
|
+
x.isProcessRunning = await isScreenRunningProcess(x.pid);
|
|
165
|
+
}));
|
|
166
|
+
}
|
|
149
167
|
|
|
150
168
|
return screenList;
|
|
151
169
|
});
|
|
@@ -241,7 +259,10 @@ const resyncServices = runInSerial(measureWrap(async function resyncServices() {
|
|
|
241
259
|
let sameParameters = prevParameters === newParametersString;
|
|
242
260
|
let screenIsRunning = screenStateMap.get(screenName)?.isProcessRunning;
|
|
243
261
|
|
|
244
|
-
if (sameParameters && screenIsRunning)
|
|
262
|
+
if (sameParameters && screenIsRunning) {
|
|
263
|
+
console.log(green(`Verified ${magenta(config.serviceId)} is running`));
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
245
266
|
|
|
246
267
|
console.log(`Resyncing service ${magenta(config.serviceId)}`);
|
|
247
268
|
|
|
@@ -252,20 +273,18 @@ const resyncServices = runInSerial(measureWrap(async function resyncServices() {
|
|
|
252
273
|
command: config.parameters.command,
|
|
253
274
|
});
|
|
254
275
|
await delay(2000);
|
|
255
|
-
let newScreens = await getScreenState();
|
|
276
|
+
let newScreens = await getScreenState(false);
|
|
256
277
|
let foundScreen = newScreens.find(x => x.screenName === screenName);
|
|
257
278
|
if (!foundScreen) {
|
|
258
279
|
console.error(`Just created screen ${screenName}, but it's not in the list of screens!`);
|
|
259
280
|
}
|
|
260
281
|
let isRunning = foundScreen && await isScreenRunningProcess(foundScreen.pid);
|
|
261
|
-
if (!isRunning) {
|
|
262
|
-
console.error(`Screen ${screenName} is not running, but it's in the list of screens`);
|
|
263
|
-
}
|
|
264
282
|
if (!isRunning) {
|
|
265
283
|
let prefix = getTmuxPrefix();
|
|
266
284
|
let logs = await runPromise(`${prefix}tmux capture-pane -t ${screenName} -p`);
|
|
267
285
|
throw new Error(`${logs}\n\nService ${magenta(config.serviceId)} is not running after starting. Trying again in ${formatTime(MACHINE_RESYNC_INTERVAL)}, or on next change. Last logs above.`);
|
|
268
286
|
}
|
|
287
|
+
console.log(green(`Service ${magenta(config.serviceId)} is verified to be running after starting.`));
|
|
269
288
|
|
|
270
289
|
machineInfo.services[config.serviceId] = {
|
|
271
290
|
lastLaunchedTime: Date.now(),
|
|
@@ -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,
|