From 563ea0eb780bc8c7799fb8d9d4a94aa89ca5c344 Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sun, 2 Aug 2026 17:57:22 -0400 Subject: [PATCH] Log AI requests, and stop hiding a failed job-file write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is no nginx access log on this host and the CSRF prepend exits with an empty body, so a request that never arrived and one that arrived and failed were indistinguishable — the page just sat at "starting…". The job-file write was also suppressed with @, which would produce exactly that hang: a token returned for a job that can never report. --- Plugin/unraid/api/ai.php | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Plugin/unraid/api/ai.php b/Plugin/unraid/api/ai.php index 2d67f00..6744636 100644 --- a/Plugin/unraid/api/ai.php +++ b/Plugin/unraid/api/ai.php @@ -85,6 +85,21 @@ const VV_AI_JOB_TTL = 3600; // seconds before a job file is reaped $isPost = $_SERVER['REQUEST_METHOD'] === 'POST'; $action = trim($isPost ? ($_POST['action'] ?? '') : ($_GET['action'] ?? 'stats')); +// Request trace. There is no nginx access log on this host and the CSRF prepend exits with an +// empty body, so without this there is no way to tell "the request never arrived" from "the +// request arrived and failed" — which is exactly the ambiguity that made the first hang +// undiagnosable. Excludes poll, which would otherwise write a line per second per open tab. +function vv_ai_log(string $msg): void { + if (!is_dir('/var/log/varaverk')) return; + @file_put_contents('/var/log/varaverk/ai.log', + date('Y-m-d H:i:s') . ' ' . $msg . "\n", FILE_APPEND | LOCK_EX); +} +if ($action !== 'poll') { + vv_ai_log(sprintf('%s action=%s from=%s', + $_SERVER['REQUEST_METHOD'] ?? '?', $action ?: '(none)', + $_SERVER['REMOTE_ADDR'] ?? '?')); +} + // ── stats ───────────────────────────────────────────────────────────────────── if ($action === 'stats') { echo json_encode(['ok' => true, 'stats' => vv_ai_stats()]); @@ -169,7 +184,13 @@ if ($action === 'ask') { echo json_encode(['ok' => false, 'error' => 'ai_chat_worker.php not found']); exit; } - @file_put_contents($jobFile, json_encode(['status' => 'pending'])); + // Not suppressed: if the job file cannot be written the worker has nowhere to report and + // the page polls a token that will never resolve — which looks exactly like a hang. + if (file_put_contents($jobFile, json_encode(['status' => 'pending'])) === false) { + vv_ai_log('ask FAILED — cannot write ' . $jobFile); + echo json_encode(['ok' => false, 'error' => 'Cannot write job file to ' . VV_AI_JOB_DIR]); + exit; + } $cmd = 'nohup php ' . escapeshellarg($worker) . ' ' . escapeshellarg($jobFile) . ' ' @@ -178,7 +199,10 @@ if ($action === 'ask') { . escapeshellarg($kind) . ' ' . escapeshellarg(($_POST['think'] ?? '1') === '1' ? '1' : '0') . ' >/dev/null 2>&1 true, 'token' => $token]); exit;