Keep daemon logs after a button restart
This commit is contained in:
@@ -40,6 +40,9 @@ mobile draft at 390px.
|
||||
- [x] C11 preview caching: Discord-hosted image/GIF previews (WebP 320px, hash-addressed, 5 MiB
|
||||
cap, one attempt) run after every walk in both modes. Live run `...-20260916090722`:
|
||||
`previewed: 2`; thumbs served over `/api/media/<scrape>/<item>/thumb` (200).
|
||||
- [x] C41 Restart keeps its logs. A button restart spawned the replacement with `stdio: ignore`,
|
||||
so anything after the restart vanished. The replacement now appends to `daemon.log` beside the
|
||||
token file (`VESKSLOP_DAEMON_LOG` overrides); documented in [docs/daemon.md](docs/daemon.md).
|
||||
- [x] C40 Stale scrape states. Two `general_chut` scrapes showed `running` because the daemons
|
||||
that owned them were killed mid-job; the state file kept the last written value. On daemon
|
||||
start the engine now reconciles `running`/`queued` scrapes to `paused`, and History has a
|
||||
|
||||
@@ -145,6 +145,14 @@ Core tab and the `/api/core/*` routes use it.
|
||||
Verified live on 2026-09-13: the web UI started the client under auto-Xvfb, the bridge connected,
|
||||
`state.get` returned the real account and guilds, and stop exited with code 0.
|
||||
|
||||
## Self-restart
|
||||
|
||||
`POST /api/daemon/restart` (Settings → Server → **Restart daemon**) replaces the daemon process
|
||||
without touching the client. The replacement detaches, so the terminal or parent shell can close.
|
||||
It appends stdout and stderr to `daemon.log` next to the token file (`poc/daemon.log` by default;
|
||||
`VESKSLOP_DAEMON_LOG` overrides). On start it pauses scrapes still marked `running` by a previous
|
||||
daemon, so a hard kill never leaves ghost jobs.
|
||||
|
||||
## Health endpoint
|
||||
|
||||
`GET /health` returns the core connection state, the socket path, the owner ID, and the query count.
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
import { spawn } from "node:child_process";
|
||||
import { closeSync, openSync } from "node:fs";
|
||||
import { config as loadEnv } from "dotenv";
|
||||
import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
|
||||
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
||||
@@ -1051,14 +1052,18 @@ function restartDaemon(): void {
|
||||
const args = [...process.execArgv, ...process.argv.slice(1)];
|
||||
const command = `${quote(process.execPath)} ${args.map(quote).join(" ")}`;
|
||||
|
||||
console.log("[daemon] restart requested: spawning a replacement");
|
||||
const logPath = process.env.VESKSLOP_DAEMON_LOG ?? join(dirname(tokenFile), "daemon.log");
|
||||
console.log(`[daemon] restart requested: spawning a replacement, appending to ${logPath}`);
|
||||
|
||||
const logFd = openSync(logPath, "a");
|
||||
const child = spawn("sh", ["-c", `sleep 2; exec ${command}`], {
|
||||
detached: true,
|
||||
stdio: "ignore",
|
||||
stdio: ["ignore", logFd, logFd],
|
||||
cwd: process.cwd(),
|
||||
env: { ...process.env, VESKSLOP_DAEMON_RESTART: "1" }
|
||||
});
|
||||
child.unref();
|
||||
closeSync(logFd);
|
||||
|
||||
setTimeout(() => shutdown(true), 300);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user