fix: improve terminal robustness with exponential backoff and better keepalive
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 3m11s
Deploy Dashboard (Dev) / deploy-dev (push) Successful in 3m11s
- Backend: Add 10s connection timeout, improve SSH keepalive (15s × 8 retries) - Backend: Add detailed error logging for debugging - Frontend: Implement exponential backoff (1s → 30s max) instead of fixed 2s - Frontend: Reduce heartbeat to 12s (within 15s SSH keepalive window) - Frontend: Reset reconnect counter on successful connection - Frontend: Fix race condition in auth recovery after manual close
This commit is contained in:
@@ -194,6 +194,8 @@
|
||||
let closedManually = false;
|
||||
let reconnecting = false;
|
||||
let authRecoveryInFlight = false;
|
||||
let reconnectAttempts = 0;
|
||||
const MAX_RECONNECT_DELAY = 30000;
|
||||
|
||||
function clearHeartbeat() {
|
||||
if (heartbeat) {
|
||||
@@ -229,17 +231,19 @@
|
||||
clearHeartbeat();
|
||||
if (closedManually || reconnectTimer) return;
|
||||
reconnecting = true;
|
||||
reconnectAttempts++;
|
||||
const delay = Math.min(1000 * Math.pow(2, reconnectAttempts - 1), MAX_RECONNECT_DELAY);
|
||||
updateTab(tabId, {
|
||||
connected: false,
|
||||
error: `${reason} — reconnecting...`,
|
||||
error: `${reason} — reconnecting in ${Math.round(delay / 1000)}s (attempt ${reconnectAttempts})...`,
|
||||
statusBanner: tab.persistent ? "Reconnecting to persistent session..." : "",
|
||||
});
|
||||
term.write(`\r\n\x1b[90m[${reason} — reconnecting...]\x1b[0m`);
|
||||
term.write(`\r\n\x1b[90m[${reason} — reconnecting in ${Math.round(delay / 1000)}s...]\x1b[0m`);
|
||||
reconnectTimer = setTimeout(() => {
|
||||
reconnectTimer = null;
|
||||
if (!tabData.has(tabId) || closedManually) return;
|
||||
connect(true);
|
||||
}, 2000);
|
||||
}, delay);
|
||||
}
|
||||
|
||||
function sendSize(ws) {
|
||||
@@ -267,6 +271,7 @@
|
||||
ws.binaryType = "arraybuffer";
|
||||
|
||||
ws.onopen = () => {
|
||||
reconnectAttempts = 0;
|
||||
updateTab(tabId, {
|
||||
connected: true,
|
||||
error: "",
|
||||
@@ -276,7 +281,7 @@
|
||||
clearHeartbeat();
|
||||
heartbeat = setInterval(() => {
|
||||
if (ws.readyState === 1) ws.send("__ping__");
|
||||
}, 25000);
|
||||
}, 12000);
|
||||
const d = tabData.get(tabId);
|
||||
if (d) {
|
||||
d.ws = ws;
|
||||
@@ -311,7 +316,7 @@
|
||||
authRecoveryInFlight = true;
|
||||
const refreshed = await tryRefreshSession();
|
||||
authRecoveryInFlight = false;
|
||||
if (refreshed) {
|
||||
if (refreshed && !closedManually) {
|
||||
reconnecting = true;
|
||||
updateTab(tabId, {
|
||||
connected: false,
|
||||
|
||||
Reference in New Issue
Block a user