fix: replace SSE with polling in live feed to stop blocking FPM workers
SSE kept a PHP-FPM worker open for 28s per connection, blocking the whole server with only 20 workers shared across all vhosts. Polling with setInterval(3000) releases the worker on each request immediately. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
c702dbadc1
commit
483cc4797e
@@ -115,7 +115,7 @@ function togglePause() {
|
||||
paused = !paused;
|
||||
document.getElementById('btnPause').innerHTML = paused ? '▶ Reanudar' : '▮▮ Pausar';
|
||||
document.getElementById('dot').className = 'dot' + (paused ? ' paused' : '');
|
||||
if (paused) { document.getElementById('status').textContent = 'En pausa'; es && es.close(); }
|
||||
if (paused) { document.getElementById('status').textContent = 'En pausa'; clearInterval(pollTimer); pollTimer = null; }
|
||||
else { connect(); }
|
||||
}
|
||||
|
||||
@@ -154,17 +154,28 @@ function addCards(rows) {
|
||||
}
|
||||
}
|
||||
|
||||
function connect() {
|
||||
es = new EventSource('/admin/webhook/stream/sse');
|
||||
es.onopen = () => {
|
||||
let lastId = 0;
|
||||
let pollTimer = null;
|
||||
|
||||
async function poll() {
|
||||
if (paused) return;
|
||||
try {
|
||||
const r = await fetch('/admin/webhook/stream?after=' + lastId + (lastId === 0 ? '&init=1' : ''));
|
||||
if (!r.ok) throw new Error('HTTP ' + r.status);
|
||||
const d = await r.json();
|
||||
if (d.last_id !== undefined) { lastId = d.last_id; }
|
||||
if (d.rows && d.rows.length) { lastId = d.rows[d.rows.length-1].id; addCards(d.rows); }
|
||||
document.getElementById('dot').className = 'dot';
|
||||
document.getElementById('status').textContent = 'Conectado — tiempo real (SSE)';
|
||||
};
|
||||
es.onmessage = e => { if (!paused) try { addCards(JSON.parse(e.data)); } catch(_) {} };
|
||||
es.onerror = () => {
|
||||
document.getElementById('status').textContent = 'Conectado — polling cada 3s';
|
||||
} catch(e) {
|
||||
document.getElementById('dot').className = 'dot paused';
|
||||
document.getElementById('status').textContent = 'Reconectando...';
|
||||
};
|
||||
document.getElementById('status').textContent = 'Error de conexion, reintentando...';
|
||||
}
|
||||
}
|
||||
|
||||
function connect() {
|
||||
poll();
|
||||
pollTimer = setInterval(poll, 3000);
|
||||
}
|
||||
|
||||
function esc(s) {
|
||||
@@ -181,7 +192,7 @@ async function showRaw(id) {
|
||||
}
|
||||
function closeModal() { document.getElementById('modal').style.display = 'none'; }
|
||||
document.addEventListener('keydown', e => { if(e.key==='Escape') closeModal(); });
|
||||
window.addEventListener('pagehide', () => { es && es.close(); });
|
||||
window.addEventListener('pagehide', () => { clearInterval(pollTimer); });
|
||||
|
||||
connect();
|
||||
</script>
|
||||
@@ -261,13 +272,10 @@ HTML;
|
||||
|
||||
try {
|
||||
if ($isInit) {
|
||||
// En init devolvemos solo el último ID (sin datos) para anclar
|
||||
$stmt = db()->query('SELECT id FROM webhook_logs ORDER BY id DESC LIMIT 1');
|
||||
$row = $stmt->fetch();
|
||||
$afterId = $row ? (int)$row['id'] : 0;
|
||||
// Devolvemos array vacío — solo queremos anclar lastId en el cliente
|
||||
$row = db()->query('SELECT id FROM webhook_logs ORDER BY id DESC LIMIT 1')->fetch();
|
||||
$lastId = $row ? (int)$row['id'] : 0;
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode([]);
|
||||
echo json_encode(['rows' => [], 'last_id' => $lastId]);
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -283,12 +291,12 @@ HTML;
|
||||
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
} catch (\PDOException $e) {
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo '[]';
|
||||
echo json_encode(['rows' => [], 'last_id' => $afterId]);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
echo json_encode($rows, JSON_UNESCAPED_UNICODE);
|
||||
echo json_encode(['rows' => $rows, 'last_id' => $rows ? (int)end($rows)['id'] : $afterId], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user