Log AI requests, and stop hiding a failed job-file write
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.
This commit is contained in:
@@ -85,6 +85,21 @@ const VV_AI_JOB_TTL = 3600; // seconds before a job file is reaped
|
|||||||
$isPost = $_SERVER['REQUEST_METHOD'] === 'POST';
|
$isPost = $_SERVER['REQUEST_METHOD'] === 'POST';
|
||||||
$action = trim($isPost ? ($_POST['action'] ?? '') : ($_GET['action'] ?? 'stats'));
|
$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 ─────────────────────────────────────────────────────────────────────
|
// ── stats ─────────────────────────────────────────────────────────────────────
|
||||||
if ($action === 'stats') {
|
if ($action === 'stats') {
|
||||||
echo json_encode(['ok' => true, 'stats' => vv_ai_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;
|
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) . ' '
|
$cmd = 'nohup php ' . escapeshellarg($worker) . ' '
|
||||||
. escapeshellarg($jobFile) . ' '
|
. escapeshellarg($jobFile) . ' '
|
||||||
@@ -178,7 +199,10 @@ if ($action === 'ask') {
|
|||||||
. escapeshellarg($kind) . ' '
|
. escapeshellarg($kind) . ' '
|
||||||
. escapeshellarg(($_POST['think'] ?? '1') === '1' ? '1' : '0')
|
. escapeshellarg(($_POST['think'] ?? '1') === '1' ? '1' : '0')
|
||||||
. ' >/dev/null 2>&1 </dev/null &';
|
. ' >/dev/null 2>&1 </dev/null &';
|
||||||
exec($cmd);
|
$out = []; $rc = 0;
|
||||||
|
exec($cmd, $out, $rc);
|
||||||
|
vv_ai_log(sprintf('ask token=%s rc=%d kind=%s q=%s',
|
||||||
|
substr($token, 0, 12), $rc, $kind ?: '-', mb_substr($question, 0, 80)));
|
||||||
|
|
||||||
echo json_encode(['ok' => true, 'token' => $token]);
|
echo json_encode(['ok' => true, 'token' => $token]);
|
||||||
exit;
|
exit;
|
||||||
|
|||||||
Reference in New Issue
Block a user