Fix logs tab stuck on Loading after switching away and back.
Release rolling / release (push) Successful in 9m0s
Release rolling / release (push) Successful in 9m0s
This commit is contained in:
+26
-10
@@ -91,13 +91,20 @@ async function startLogStream(session, streams, args) {
|
||||
const containerId = args.id || args.containerId
|
||||
if (!containerId) throw new Error('container id required')
|
||||
|
||||
if (streams.has(containerId)) {
|
||||
// Tear down any existing stream for this container first. Mark it dead so
|
||||
// late error/end events from the old stream cannot clear the new entry.
|
||||
const prev = streams.get(containerId)
|
||||
if (prev) {
|
||||
prev.dead = true
|
||||
try {
|
||||
streams.get(containerId).stream?.destroy?.()
|
||||
prev.stream?.removeAllListeners?.()
|
||||
prev.stream?.destroy?.()
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
streams.delete(containerId)
|
||||
// Brief yield so docker-modem can release the hijacked socket before re-attach
|
||||
await new Promise((r) => setTimeout(r, 50))
|
||||
}
|
||||
|
||||
const logOpts = {
|
||||
@@ -112,10 +119,13 @@ async function startLogStream(session, streams, args) {
|
||||
|
||||
const logsStream = await docker.getContainer(containerId).logs(logOpts)
|
||||
const demux = createServerDemuxer()
|
||||
const gen = (prev?.gen || 0) + 1
|
||||
const entry = { stream: logsStream, demux, gen, dead: false }
|
||||
|
||||
streams.set(containerId, { stream: logsStream, demux })
|
||||
streams.set(containerId, entry)
|
||||
|
||||
logsStream.on('data', (chunk) => {
|
||||
if (entry.dead || streams.get(containerId) !== entry) return
|
||||
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)
|
||||
const payloads = demux.push(buf)
|
||||
for (const payload of payloads) {
|
||||
@@ -134,6 +144,7 @@ async function startLogStream(session, streams, args) {
|
||||
}
|
||||
})
|
||||
logsStream.on('end', () => {
|
||||
if (entry.dead) return
|
||||
for (const payload of demux.flush()) {
|
||||
if (!payload.length) continue
|
||||
try {
|
||||
@@ -148,18 +159,23 @@ async function startLogStream(session, streams, args) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
streams.delete(containerId)
|
||||
if (streams.get(containerId) === entry) streams.delete(containerId)
|
||||
})
|
||||
logsStream.on('error', (err) => {
|
||||
if (entry.dead) return
|
||||
logger.error('Log stream error', { containerId, error: err.message })
|
||||
session.push(Pushes.error, {
|
||||
error: `Log stream error: ${err.message}`,
|
||||
containerId,
|
||||
})
|
||||
streams.delete(containerId)
|
||||
try {
|
||||
session.push(Pushes.error, {
|
||||
error: `Log stream error: ${err.message}`,
|
||||
containerId,
|
||||
})
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
if (streams.get(containerId) === entry) streams.delete(containerId)
|
||||
})
|
||||
|
||||
return { success: true, message: `Log stream started for ${containerId}` }
|
||||
return { success: true, message: `Log stream started for ${containerId}`, containerId }
|
||||
}
|
||||
|
||||
export function registerLogsHandlers(session) {
|
||||
|
||||
Reference in New Issue
Block a user