bgrun 3.10.1 → 3.10.2
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/dashboard/app/api/guard/route.ts +50 -0
- package/dist/index.js +17 -1
- package/package.json +1 -1
- package/src/db.ts +8 -0
- package/src/server.ts +13 -9
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* POST /api/guard — Toggle BGR_KEEP_ALIVE for a process
|
|
3
|
+
* Body: { name: string, enabled: boolean }
|
|
4
|
+
*
|
|
5
|
+
* When enabled=true, the built-in guard will auto-restart this process if it dies.
|
|
6
|
+
* When enabled=false, the process is left alone.
|
|
7
|
+
*/
|
|
8
|
+
import { getProcess, updateProcessEnv } from '../../../src/db';
|
|
9
|
+
|
|
10
|
+
export async function POST(req: Request) {
|
|
11
|
+
try {
|
|
12
|
+
const body = await req.json() as { name: string; enabled: boolean };
|
|
13
|
+
if (!body.name) {
|
|
14
|
+
return Response.json({ error: 'Missing process name' }, { status: 400 });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const proc = getProcess(body.name);
|
|
18
|
+
if (!proc) {
|
|
19
|
+
return Response.json({ error: `Process "${body.name}" not found` }, { status: 404 });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Parse existing env
|
|
23
|
+
let env: Record<string, string> = {};
|
|
24
|
+
if (proc.env) {
|
|
25
|
+
try { env = JSON.parse(proc.env); } catch { env = {}; }
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Toggle BGR_KEEP_ALIVE
|
|
29
|
+
if (body.enabled) {
|
|
30
|
+
env.BGR_KEEP_ALIVE = 'true';
|
|
31
|
+
} else {
|
|
32
|
+
delete env.BGR_KEEP_ALIVE;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Save back
|
|
36
|
+
updateProcessEnv(body.name, JSON.stringify(env));
|
|
37
|
+
|
|
38
|
+
return Response.json({
|
|
39
|
+
ok: true,
|
|
40
|
+
name: body.name,
|
|
41
|
+
guarded: body.enabled
|
|
42
|
+
});
|
|
43
|
+
} catch (err: any) {
|
|
44
|
+
return Response.json({ error: err.message }, { status: 500 });
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function GET() {
|
|
49
|
+
return Response.json({ error: 'Use POST to toggle guard' }, { status: 405 });
|
|
50
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -406,6 +406,7 @@ var init_utils = __esm(() => {
|
|
|
406
406
|
var exports_db = {};
|
|
407
407
|
__export(exports_db, {
|
|
408
408
|
updateProcessPid: () => updateProcessPid,
|
|
409
|
+
updateProcessEnv: () => updateProcessEnv,
|
|
409
410
|
retryDatabaseOperation: () => retryDatabaseOperation,
|
|
410
411
|
removeProcessByName: () => removeProcessByName,
|
|
411
412
|
removeProcess: () => removeProcess,
|
|
@@ -459,6 +460,12 @@ function removeAllProcesses() {
|
|
|
459
460
|
db.process.delete(p.id);
|
|
460
461
|
}
|
|
461
462
|
}
|
|
463
|
+
function updateProcessEnv(name, envJson) {
|
|
464
|
+
const proc = db.process.select().where({ name }).limit(1).get();
|
|
465
|
+
if (proc) {
|
|
466
|
+
db.process.update(proc.id, { env: envJson });
|
|
467
|
+
}
|
|
468
|
+
}
|
|
462
469
|
function getDbInfo() {
|
|
463
470
|
return {
|
|
464
471
|
dbPath,
|
|
@@ -753,9 +760,18 @@ function startGuard() {
|
|
|
753
760
|
for (const proc of processes) {
|
|
754
761
|
if (GUARD_SKIP_NAMES.has(proc.name))
|
|
755
762
|
continue;
|
|
763
|
+
const env = proc.env ? typeof proc.env === "string" ? (() => {
|
|
764
|
+
try {
|
|
765
|
+
return JSON.parse(proc.env);
|
|
766
|
+
} catch {
|
|
767
|
+
return {};
|
|
768
|
+
}
|
|
769
|
+
})() : proc.env : {};
|
|
770
|
+
if (env.BGR_KEEP_ALIVE !== "true")
|
|
771
|
+
continue;
|
|
756
772
|
const alive = await isProcessRunning(proc.pid, proc.command);
|
|
757
773
|
if (!alive) {
|
|
758
|
-
console.log(`[guard] \u26A0
|
|
774
|
+
console.log(`[guard] \u26A0 Guarded process "${proc.name}" (PID ${proc.pid}) is dead, restarting...`);
|
|
759
775
|
try {
|
|
760
776
|
await handleRun({
|
|
761
777
|
action: "run",
|
package/package.json
CHANGED
package/src/db.ts
CHANGED
|
@@ -119,6 +119,14 @@ export function removeAllProcesses() {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
/** Update the stored env JSON for a process (used by guard toggle) */
|
|
123
|
+
export function updateProcessEnv(name: string, envJson: string) {
|
|
124
|
+
const proc = db.process.select().where({ name }).limit(1).get();
|
|
125
|
+
if (proc) {
|
|
126
|
+
db.process.update(proc.id, { env: envJson });
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
122
130
|
// =============================================================================
|
|
123
131
|
// DEBUG / INFO
|
|
124
132
|
// =============================================================================
|
package/src/server.ts
CHANGED
|
@@ -44,15 +44,15 @@ export async function startServer() {
|
|
|
44
44
|
* Built-in Process Guard
|
|
45
45
|
*
|
|
46
46
|
* Runs as a background loop inside the dashboard process.
|
|
47
|
-
* Every GUARD_INTERVAL_MS,
|
|
48
|
-
*
|
|
49
|
-
* handleRun with force=true (same as `bgrun --restart <name>`).
|
|
47
|
+
* Every GUARD_INTERVAL_MS, checks processes with BGR_KEEP_ALIVE=true
|
|
48
|
+
* in their env and auto-restarts any that died.
|
|
50
49
|
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
50
|
+
* Only guarded processes (opted-in via dashboard toggle or env var) are
|
|
51
|
+
* monitored. Other processes are left alone even if they crash.
|
|
52
|
+
*
|
|
53
|
+
* Toggle guard per-process:
|
|
54
|
+
* - Dashboard UI: click the shield icon on any process row
|
|
55
|
+
* - CLI: set BGR_KEEP_ALIVE=true in the process env/config
|
|
56
56
|
*/
|
|
57
57
|
function startGuard() {
|
|
58
58
|
console.log(`[guard] ✓ Built-in process guard started (checking every ${GUARD_INTERVAL_MS / 1000}s)`);
|
|
@@ -66,9 +66,13 @@ function startGuard() {
|
|
|
66
66
|
// Skip the dashboard itself
|
|
67
67
|
if (GUARD_SKIP_NAMES.has(proc.name)) continue;
|
|
68
68
|
|
|
69
|
+
// Only guard processes with BGR_KEEP_ALIVE=true
|
|
70
|
+
const env = proc.env ? (typeof proc.env === 'string' ? (() => { try { return JSON.parse(proc.env); } catch { return {}; } })() : proc.env) : {};
|
|
71
|
+
if (env.BGR_KEEP_ALIVE !== 'true') continue;
|
|
72
|
+
|
|
69
73
|
const alive = await isProcessRunning(proc.pid, proc.command);
|
|
70
74
|
if (!alive) {
|
|
71
|
-
console.log(`[guard] ⚠
|
|
75
|
+
console.log(`[guard] ⚠ Guarded process "${proc.name}" (PID ${proc.pid}) is dead, restarting...`);
|
|
72
76
|
try {
|
|
73
77
|
await handleRun({
|
|
74
78
|
action: 'run',
|