Fix Uptime Kuma listResources missing monitorList/heartbeat events
Listeners for monitorList/importantHeartbeatList/heartbeat were being attached after the login ack resolved, but the server pushes that data right after login — sometimes in the same tick as the ack — so Socket.IO dropped it before a listener existed. Listeners now attach before login is sent.
This commit is contained in:
parent
89dd3471db
commit
f390e8c586
1 changed files with 13 additions and 8 deletions
|
|
@ -23,9 +23,14 @@ function connectAndLogin(
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
username: string,
|
username: string,
|
||||||
password: string,
|
password: string,
|
||||||
|
onSocket?: (socket: Socket) => void,
|
||||||
): Promise<Socket> {
|
): Promise<Socket> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const socket = io(baseUrl, { transports: ['websocket', 'polling'], reconnection: false, timeout: 10000 })
|
const socket = io(baseUrl, { transports: ['websocket', 'polling'], reconnection: false, timeout: 10000 })
|
||||||
|
// Attach event listeners before the login ack arrives — Uptime Kuma's
|
||||||
|
// server pushes monitorList/heartbeat right after login, sometimes in the
|
||||||
|
// same tick as the ack, and Socket.IO drops events with no listener yet.
|
||||||
|
onSocket?.(socket)
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
socket.disconnect()
|
socket.disconnect()
|
||||||
|
|
@ -74,22 +79,22 @@ export const uptimeKuma: IntegrationAdapter = {
|
||||||
const password = secrets.password
|
const password = secrets.password
|
||||||
if (!baseUrl || !username || !password) return []
|
if (!baseUrl || !username || !password) return []
|
||||||
|
|
||||||
const socket = await connectAndLogin(baseUrl, username, password)
|
const monitors = new Map<number, UptimeKumaMonitor>()
|
||||||
try {
|
const lastHeartbeat = new Map<number, Heartbeat>()
|
||||||
const monitors = new Map<number, UptimeKumaMonitor>()
|
|
||||||
const lastHeartbeat = new Map<number, Heartbeat>()
|
|
||||||
|
|
||||||
socket.on('monitorList', (list: Record<string, UptimeKumaMonitor>) => {
|
const socket = await connectAndLogin(baseUrl, username, password, (s) => {
|
||||||
|
s.on('monitorList', (list: Record<string, UptimeKumaMonitor>) => {
|
||||||
for (const m of Object.values(list)) monitors.set(m.id, m)
|
for (const m of Object.values(list)) monitors.set(m.id, m)
|
||||||
})
|
})
|
||||||
socket.on('importantHeartbeatList', (monitorId: number, beats: Heartbeat[]) => {
|
s.on('importantHeartbeatList', (monitorId: number, beats: Heartbeat[]) => {
|
||||||
const latest = beats[beats.length - 1]
|
const latest = beats[beats.length - 1]
|
||||||
if (latest) lastHeartbeat.set(monitorId, latest)
|
if (latest) lastHeartbeat.set(monitorId, latest)
|
||||||
})
|
})
|
||||||
socket.on('heartbeat', (beat: Heartbeat & { monitorID: number }) => {
|
s.on('heartbeat', (beat: Heartbeat & { monitorID: number }) => {
|
||||||
lastHeartbeat.set(beat.monitorID, beat)
|
lastHeartbeat.set(beat.monitorID, beat)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
try {
|
||||||
// Server pushes these events asynchronously right after login — there's no
|
// Server pushes these events asynchronously right after login — there's no
|
||||||
// single "done" signal, so give it a short window to arrive.
|
// single "done" signal, so give it a short window to arrive.
|
||||||
await new Promise((resolve) => setTimeout(resolve, 2500))
|
await new Promise((resolve) => setTimeout(resolve, 2500))
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue