querysub 0.558.0 → 0.559.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
|
@@ -26,7 +26,7 @@ import { PromiseObj } from "../promise";
|
|
|
26
26
|
import path from "path";
|
|
27
27
|
import { fsExistsAsync } from "../fs";
|
|
28
28
|
import { ALIVE_WINDOW_FOREVER, ParametersTimelineEntry, syncParametersTimelineFiles } from "./parametersTimeline";
|
|
29
|
-
import { getScreenName, getFutureScreenName, getTmuxPrefix, getScreenState, isScreenRunningProcess, getProcessStartTime, runScreenCommand, killScreen, streamProcessOutput } from "./processManager";
|
|
29
|
+
import { getScreenName, getFutureScreenName, getTmuxPrefix, getScreenState, isScreenRunningProcess, getProcessStartTime, ensureProcessRecord, runScreenCommand, killScreen, streamProcessOutput } from "./processManager";
|
|
30
30
|
import { ProcessRecord, syncProcessRecords, writeProcessRecord, listProcessRecords, getProcessLogPath } from "./processLogs";
|
|
31
31
|
|
|
32
32
|
|
|
@@ -288,6 +288,19 @@ async function ensureFutureStarted(config: FutureConfig) {
|
|
|
288
288
|
let existing = config.screenStateMap.get(futureScreenName);
|
|
289
289
|
if (existing?.isProcessRunning) {
|
|
290
290
|
config.screenNamesUsed.add(futureScreenName);
|
|
291
|
+
// Started before we restarted, so record it rather than only ever recording processes we launched ourselves
|
|
292
|
+
await ensureProcessRecord({
|
|
293
|
+
screenName: futureScreenName,
|
|
294
|
+
folder: os.homedir() + "/" + SERVICE_FOLDER + canonicalScreenName + "/",
|
|
295
|
+
panePid: existing.pid,
|
|
296
|
+
record: {
|
|
297
|
+
serviceId: config.serviceId,
|
|
298
|
+
serviceKey: config.next.key,
|
|
299
|
+
index: config.index,
|
|
300
|
+
machineId: config.machineId,
|
|
301
|
+
parameters: config.next,
|
|
302
|
+
},
|
|
303
|
+
});
|
|
291
304
|
console.log(green(`Verified future instance ${magenta(futureScreenName)} is running`));
|
|
292
305
|
return;
|
|
293
306
|
}
|
|
@@ -515,6 +528,22 @@ const resyncServicesBase = runInSerial(measureWrap(async function resyncServices
|
|
|
515
528
|
if (isPrepTime) {
|
|
516
529
|
// From prep time on, the canonical (old) screen is left completely untouched — the folder holds the NEW code and parameters by now, so the normal compare/sync logic below must not run against the old process
|
|
517
530
|
if (screenStateMap.get(screenName)?.isProcessRunning) {
|
|
531
|
+
// The old instance keeps running untouched through the overlap, but it still needs a record - it may have been launched before we restarted
|
|
532
|
+
let panePid = screenStateMap.get(screenName)?.pid;
|
|
533
|
+
if (panePid) {
|
|
534
|
+
await ensureProcessRecord({
|
|
535
|
+
screenName,
|
|
536
|
+
folder,
|
|
537
|
+
panePid,
|
|
538
|
+
record: {
|
|
539
|
+
serviceId: config.serviceId,
|
|
540
|
+
serviceKey: config.parameters.key,
|
|
541
|
+
index: i,
|
|
542
|
+
machineId,
|
|
543
|
+
parameters: instanceParameters,
|
|
544
|
+
},
|
|
545
|
+
});
|
|
546
|
+
}
|
|
518
547
|
await syncTimeline(screenStateMap.get(screenName)?.pid);
|
|
519
548
|
let nodePathId = folder + SERVICE_NODE_FILE_NAME;
|
|
520
549
|
if (await fsExistsAsync(nodePathId)) {
|
|
@@ -573,6 +602,22 @@ const resyncServicesBase = runInSerial(measureWrap(async function resyncServices
|
|
|
573
602
|
if (prevParameters !== newParametersString) {
|
|
574
603
|
await fs.promises.writeFile(parameterPath, newParametersString);
|
|
575
604
|
}
|
|
605
|
+
// We did not launch this process (we restarted, or it predates process records), so make sure it is recorded before we leave it alone
|
|
606
|
+
let panePid = screenStateMap.get(screenName)?.pid;
|
|
607
|
+
if (panePid) {
|
|
608
|
+
await ensureProcessRecord({
|
|
609
|
+
screenName,
|
|
610
|
+
folder,
|
|
611
|
+
panePid,
|
|
612
|
+
record: {
|
|
613
|
+
serviceId: config.serviceId,
|
|
614
|
+
serviceKey: config.parameters.key,
|
|
615
|
+
index: i,
|
|
616
|
+
machineId,
|
|
617
|
+
parameters: instanceParameters,
|
|
618
|
+
},
|
|
619
|
+
});
|
|
620
|
+
}
|
|
576
621
|
await syncTimeline(screenStateMap.get(screenName)?.pid);
|
|
577
622
|
console.log(green(`Verified ${magenta(screenName)} is running`));
|
|
578
623
|
continue;
|
|
@@ -11,7 +11,7 @@ import { forceRemoveNode } from "../-f-node-discovery/NodeDiscovery";
|
|
|
11
11
|
import { fsExistsAsync } from "../fs";
|
|
12
12
|
import { PromiseObj } from "../promise";
|
|
13
13
|
import { SERVICE_FOLDER, SERVICE_NODE_FILE_NAME } from "./machineSchema";
|
|
14
|
-
import { ProcessRecord, createLaunchId, getLogPipeScript, getLogTailScript, getProcessLogPath, getPipeScriptPath, getTailScriptPath, writeProcessRecord } from "./processLogs";
|
|
14
|
+
import { ProcessRecord, createLaunchId, getLogPipeScript, getLogTailScript, getProcessLogPath, getPipeScriptPath, getTailScriptPath, listProcessRecords, writeProcessRecord } from "./processLogs";
|
|
15
15
|
|
|
16
16
|
// Running, inspecting and killing the tmux screens services run in. This layer only knows "here is a configuration, run it" - which version should be running when is the deploy logic's problem.
|
|
17
17
|
|
|
@@ -244,6 +244,38 @@ ${config.command}
|
|
|
244
244
|
return launchId;
|
|
245
245
|
});
|
|
246
246
|
|
|
247
|
+
/** Links an already-running screen to a process record, creating one when this process has never been recorded - it was launched before we restarted, or before process records existed at all. Idempotent: a process we already know about is left alone, so the pipe is only attached the first time we adopt it.
|
|
248
|
+
*
|
|
249
|
+
* The screen identifies itself (pane pid + the start time the OS reports for it), so adoption is just naming what is already there - there is nothing to reconcile and nothing to guess. */
|
|
250
|
+
export async function ensureProcessRecord(config: {
|
|
251
|
+
screenName: string;
|
|
252
|
+
folder: string;
|
|
253
|
+
panePid: string;
|
|
254
|
+
record: Omit<ProcessRecord, "launchId" | "folder" | "screenName" | "startTime" | "pid">;
|
|
255
|
+
}): Promise<void> {
|
|
256
|
+
let startTime = await getProcessStartTime(config.panePid);
|
|
257
|
+
if (!startTime) return;
|
|
258
|
+
let launchId = createLaunchId(config.panePid, startTime);
|
|
259
|
+
let existing = (await listProcessRecords()).find(x => x.launchId === launchId && x.folder === config.folder);
|
|
260
|
+
if (existing) {
|
|
261
|
+
// A takeover renames the session, so the record follows the name it now runs under
|
|
262
|
+
if (existing.screenName === config.screenName) return;
|
|
263
|
+
await writeProcessRecord({ ...existing, screenName: config.screenName });
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
console.log(`Adopting already-running process ${launchId} on screen ${config.screenName}, which has no record yet`);
|
|
267
|
+
await writeProcessRecord({
|
|
268
|
+
...config.record,
|
|
269
|
+
launchId,
|
|
270
|
+
folder: config.folder,
|
|
271
|
+
screenName: config.screenName,
|
|
272
|
+
pid: parseInt(config.panePid) || undefined,
|
|
273
|
+
startTime,
|
|
274
|
+
});
|
|
275
|
+
// Its output was going to whatever the previous incarnation pointed at (or nowhere), so point it at its own log from here on
|
|
276
|
+
await setupPipePane({ screenName: config.screenName, folder: config.folder, launchId });
|
|
277
|
+
}
|
|
278
|
+
|
|
247
279
|
// Points the screen's pipe-pane at this launch's own log file.
|
|
248
280
|
async function setupPipePane(config: { screenName: string; folder: string; launchId: string }) {
|
|
249
281
|
let prefix = getTmuxPrefix();
|