bridge: fix exponential reconnect (OOM) + add dataref resolve probe
The X-Plane socket fired both 'error' and 'close' on a failed connect, each scheduling a reconnect — so attempts doubled every cycle, leaking sockets/timers until the process OOMed (~3 min with the sim down). Guard onDown so each socket schedules exactly one reconnect (and tear the dead socket down). Also log a one-shot resolve-probe (GET /datarefs?filter[name]=airspeed…) on connect so a Web-API version/format mismatch is visible in the log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -79,6 +79,15 @@ async function fetchAllByName(resource, names) {
|
||||
|
||||
// ---- X-Plane connection ---------------------------------------------------
|
||||
async function resolveIds() {
|
||||
// one-shot diagnostic: probe a universal dataref so the log shows the API's
|
||||
// real response shape (helps when a version/format mismatch yields 0 matches).
|
||||
try {
|
||||
const probe = 'sim/cockpit2/gauges/indicators/airspeed_kts_pilot';
|
||||
const u = `${REST}/datarefs?filter[name]=${encodeURIComponent(probe)}`;
|
||||
const r = await fetch(u, { headers: { Accept: 'application/json' } });
|
||||
const txt = await r.text();
|
||||
log(`resolve-probe: GET ${u} -> HTTP ${r.status}; body ${txt.slice(0, 160)}`);
|
||||
} catch (e) { log(`resolve-probe failed: ${e.message}`); }
|
||||
const drefNames = Object.values(DATAREFS);
|
||||
const cmdNames = Object.values(COMMANDS);
|
||||
state.drefNameToId = await fetchAllByName('datarefs', [
|
||||
@@ -146,11 +155,18 @@ function connectXPlane() {
|
||||
}
|
||||
});
|
||||
|
||||
// 'error' and 'close' both fire on a failed socket — guard so each socket
|
||||
// schedules exactly ONE reconnect (otherwise attempts double every cycle and
|
||||
// the process leaks sockets/timers until it OOMs).
|
||||
let downHandled = false;
|
||||
const onDown = (why) => {
|
||||
if (downHandled) return;
|
||||
downHandled = true;
|
||||
if (state.xpConnected) log(`X-Plane disconnected (${why})`);
|
||||
state.xpConnected = false;
|
||||
broadcast({ type: 'status', xpConnected: false });
|
||||
if (state.xpSocket === sock) state.xpSocket = null;
|
||||
try { sock.removeAllListeners(); sock.terminate?.(); } catch {}
|
||||
setTimeout(connectXPlane, 3000);
|
||||
};
|
||||
sock.on('close', () => onDown('close'));
|
||||
|
||||
Reference in New Issue
Block a user