feat (ui): exec fase 5
This commit is contained in:
@@ -420,6 +420,9 @@ let execTerminalState = {
|
||||
outputText: '',
|
||||
outputLineCount: 0,
|
||||
outputTruncated: false,
|
||||
sessionInfo: null,
|
||||
infoPollTimer: null,
|
||||
infoTickTimer: null,
|
||||
};
|
||||
|
||||
const EXEC_OUTPUT_MAX_CHARS = 200000;
|
||||
@@ -430,6 +433,8 @@ const EXEC_RECONNECT_BASE_MS = 350;
|
||||
const EXEC_RECONNECT_MAX_MS = 5000;
|
||||
const EXEC_RECONNECT_MAX_ATTEMPTS = 8;
|
||||
const EXEC_PASTE_CHUNK_SIZE = 2048;
|
||||
const EXEC_SESSION_INFO_POLL_MS = 7000;
|
||||
const EXEC_IDLE_TTL_SECONDS = 60 * 60;
|
||||
|
||||
function _execEls() {
|
||||
return {
|
||||
@@ -526,7 +531,73 @@ function _execInitTerminal() {
|
||||
|
||||
function _execConnectedStatus() {
|
||||
const sid = execTerminalState.sessionId || '';
|
||||
return sid ? `Connected (${sid})` : 'Connected';
|
||||
if (!sid) return 'Connected';
|
||||
const info = execTerminalState.sessionInfo;
|
||||
if (!info) return `Connected (${sid})`;
|
||||
if (info.closed) return `Session closed: ${info.close_reason || 'closed'}`;
|
||||
|
||||
const last = Number(info.last_activity || 0);
|
||||
if (!Number.isFinite(last) || last <= 0) return `Connected (${sid})`;
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
const idleAge = Math.max(0, now - last);
|
||||
const idleLeft = Math.max(0, EXEC_IDLE_TTL_SECONDS - idleAge);
|
||||
const mm = String(Math.floor(idleLeft / 60)).padStart(2, '0');
|
||||
const ss = String(idleLeft % 60).padStart(2, '0');
|
||||
return `Connected (${sid}) - idle in ${mm}:${ss}`;
|
||||
}
|
||||
|
||||
function _execStopSessionInfoTimers() {
|
||||
if (execTerminalState.infoPollTimer) {
|
||||
clearInterval(execTerminalState.infoPollTimer);
|
||||
execTerminalState.infoPollTimer = null;
|
||||
}
|
||||
if (execTerminalState.infoTickTimer) {
|
||||
clearInterval(execTerminalState.infoTickTimer);
|
||||
execTerminalState.infoTickTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function _execCanUpdateConnectedStatus() {
|
||||
if (!execTerminalState.sessionId) return false;
|
||||
if (
|
||||
execTerminalState.reconnectEnabled &&
|
||||
execTerminalState.reconnectAttempts > 0 &&
|
||||
!execTerminalState.source
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function _execRefreshSessionInfo() {
|
||||
const sid = execTerminalState.sessionId;
|
||||
if (!sid) return;
|
||||
try {
|
||||
const info = await api(`/containers/exec/${encodeURIComponent(sid)}`, 'GET');
|
||||
if (sid !== execTerminalState.sessionId) return;
|
||||
execTerminalState.sessionInfo = info || null;
|
||||
if (execTerminalState.sessionInfo?.closed) {
|
||||
execTerminalState.reconnectEnabled = false;
|
||||
_execCancelReconnect();
|
||||
_execCloseEventSource();
|
||||
_execSetStatus(`Session closed: ${execTerminalState.sessionInfo.close_reason || 'closed'}`);
|
||||
_execStopSessionInfoTimers();
|
||||
return;
|
||||
}
|
||||
if (_execCanUpdateConnectedStatus()) _execSetStatus(_execConnectedStatus());
|
||||
} catch (_) {
|
||||
// stream reconnect status has priority
|
||||
}
|
||||
}
|
||||
|
||||
function _execStartSessionInfoTimers() {
|
||||
_execStopSessionInfoTimers();
|
||||
_execRefreshSessionInfo();
|
||||
execTerminalState.infoPollTimer = setInterval(_execRefreshSessionInfo, EXEC_SESSION_INFO_POLL_MS);
|
||||
execTerminalState.infoTickTimer = setInterval(() => {
|
||||
if (!_execCanUpdateConnectedStatus()) return;
|
||||
_execSetStatus(_execConnectedStatus());
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function _execAppendOutput(txt) {
|
||||
@@ -888,7 +959,9 @@ async function containerExecOpen(name) {
|
||||
execTerminalState.sessionId = '';
|
||||
execTerminalState.lastSeq = 0;
|
||||
execTerminalState.reconnectEnabled = false;
|
||||
execTerminalState.sessionInfo = null;
|
||||
_execCancelReconnect();
|
||||
_execStopSessionInfoTimers();
|
||||
execTerminalState.rawMode = true;
|
||||
_execInitTerminal();
|
||||
_execUpdateInputModeUi();
|
||||
@@ -907,8 +980,10 @@ async function containerExecOpen(name) {
|
||||
execTerminalState.sessionId = sid;
|
||||
execTerminalState.lastSeq = 0;
|
||||
execTerminalState.reconnectEnabled = true;
|
||||
execTerminalState.sessionInfo = null;
|
||||
_execSetStatus(`Connected (${sid})`);
|
||||
_execAttachStream(0, false);
|
||||
_execStartSessionInfoTimers();
|
||||
|
||||
_execScheduleResize();
|
||||
|
||||
@@ -998,6 +1073,7 @@ async function containerExecClose() {
|
||||
|
||||
execTerminalState.reconnectEnabled = false;
|
||||
_execCancelReconnect();
|
||||
_execStopSessionInfoTimers();
|
||||
_execCloseEventSource();
|
||||
_execDestroyTerminal();
|
||||
_execSetTerminalUiMode(false);
|
||||
@@ -1013,6 +1089,7 @@ async function containerExecClose() {
|
||||
|
||||
execTerminalState.sessionId = '';
|
||||
execTerminalState.lastSeq = 0;
|
||||
execTerminalState.sessionInfo = null;
|
||||
if (els.back) els.back.style.display = 'none';
|
||||
|
||||
if (sid) {
|
||||
|
||||
Reference in New Issue
Block a user