This commit is contained in:
+82
-13
@@ -20,20 +20,89 @@ import logger from '../utils/logger.js'
|
||||
/** @type {Map<string, { username: string, serveraddress?: string }>} */
|
||||
const registryAuth = new Map()
|
||||
|
||||
export function registerSystemHandlers(session) {
|
||||
session.respond('ping', async () => {
|
||||
let dockerOk = false
|
||||
let apiVersion = null
|
||||
let osType = null
|
||||
let error = null
|
||||
try {
|
||||
/**
|
||||
* Cached Docker probe for high-frequency ping RPCs.
|
||||
* Clients poll health every ~10s; version() is heavier than needed every tick.
|
||||
* TTL keeps degraded detection responsive without hammering the socket.
|
||||
*/
|
||||
const PING_DOCKER_CACHE_TTL_MS = 10_000
|
||||
/** @type {{ at: number, ok: boolean, apiVersion: string|null, os: string|null, error: string|null }|null} */
|
||||
let pingDockerCache = null
|
||||
|
||||
/**
|
||||
* Lightweight Docker health for ping. Uses docker.ping() for liveness; refreshes
|
||||
* apiVersion/os via version() only when cache is cold or after a failure.
|
||||
* @returns {Promise<{ ok: boolean, apiVersion: string|null, os: string|null, error: string|null }>}
|
||||
*/
|
||||
export async function probeDockerForPing() {
|
||||
const now = Date.now()
|
||||
if (
|
||||
pingDockerCache &&
|
||||
now - pingDockerCache.at < PING_DOCKER_CACHE_TTL_MS &&
|
||||
pingDockerCache.ok
|
||||
) {
|
||||
return {
|
||||
ok: true,
|
||||
apiVersion: pingDockerCache.apiVersion,
|
||||
os: pingDockerCache.os,
|
||||
error: null,
|
||||
}
|
||||
}
|
||||
|
||||
let dockerOk = false
|
||||
let apiVersion = pingDockerCache?.apiVersion ?? null
|
||||
let osType = pingDockerCache?.os ?? null
|
||||
let error = null
|
||||
|
||||
try {
|
||||
// Prefer cheap ping; fall back to version if ping is unavailable
|
||||
if (typeof docker.ping === 'function') {
|
||||
await docker.ping()
|
||||
dockerOk = true
|
||||
// Refresh version metadata when cache empty or expired
|
||||
if (!apiVersion || !pingDockerCache || now - pingDockerCache.at >= PING_DOCKER_CACHE_TTL_MS) {
|
||||
try {
|
||||
const version = await docker.version()
|
||||
apiVersion = version.ApiVersion || version.apiVersion || apiVersion
|
||||
osType = version.Os || version.os || osType
|
||||
} catch {
|
||||
// ok remains true from ping; version is optional decoration
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const version = await docker.version()
|
||||
dockerOk = true
|
||||
apiVersion = version.ApiVersion || version.apiVersion || null
|
||||
osType = version.Os || version.os || null
|
||||
} catch (err) {
|
||||
error = err.message
|
||||
}
|
||||
} catch (err) {
|
||||
error = err.message || String(err)
|
||||
dockerOk = false
|
||||
}
|
||||
|
||||
pingDockerCache = {
|
||||
at: Date.now(),
|
||||
ok: dockerOk,
|
||||
apiVersion,
|
||||
os: osType,
|
||||
error,
|
||||
}
|
||||
return {
|
||||
ok: dockerOk,
|
||||
apiVersion,
|
||||
os: osType,
|
||||
error,
|
||||
}
|
||||
}
|
||||
|
||||
/** Test helper: clear ping Docker probe cache */
|
||||
export function clearPingDockerCache() {
|
||||
pingDockerCache = null
|
||||
}
|
||||
|
||||
export function registerSystemHandlers(session) {
|
||||
session.respond('ping', async () => {
|
||||
const dockerProbe = await probeDockerForPing()
|
||||
return {
|
||||
success: true,
|
||||
pong: Date.now(),
|
||||
@@ -41,10 +110,10 @@ export function registerSystemHandlers(session) {
|
||||
protocolVersion: PROTOCOL_VERSION,
|
||||
role: session.role,
|
||||
docker: {
|
||||
ok: dockerOk,
|
||||
apiVersion,
|
||||
os: osType,
|
||||
error,
|
||||
ok: dockerProbe.ok,
|
||||
apiVersion: dockerProbe.apiVersion,
|
||||
os: dockerProbe.os,
|
||||
error: dockerProbe.error,
|
||||
},
|
||||
features: {
|
||||
swarm: isSwarmEnabled(),
|
||||
|
||||
Reference in New Issue
Block a user