kahu-signalk 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugin/connector.js +1 -1
- package/plugin/mayara.js +57 -5
package/package.json
CHANGED
package/plugin/connector.js
CHANGED
|
@@ -75,7 +75,7 @@ class Connector {
|
|
|
75
75
|
const content = response.Response;
|
|
76
76
|
|
|
77
77
|
if (content["kahu.ErrorResponseMessage"] !== undefined) {
|
|
78
|
-
throw content.
|
|
78
|
+
throw content["kahu.ErrorResponseMessage"].exception;
|
|
79
79
|
} else if (type !== undefined && content[type] === undefined) {
|
|
80
80
|
throw (
|
|
81
81
|
"Received response for wrong method: expected " +
|
package/plugin/mayara.js
CHANGED
|
@@ -25,6 +25,7 @@ class MayaraIngestor {
|
|
|
25
25
|
this.reconnectMs = 1000;
|
|
26
26
|
this.wsFailCount = 0;
|
|
27
27
|
this.destroyed = false;
|
|
28
|
+
this.halted = false;
|
|
28
29
|
|
|
29
30
|
this.radarIds = [];
|
|
30
31
|
this.targetUuids = new Map();
|
|
@@ -53,9 +54,10 @@ class MayaraIngestor {
|
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
async start() {
|
|
57
|
+
if (this.halted) return;
|
|
56
58
|
this._log("start", { message: "starting ingestor" });
|
|
57
59
|
await this._discoverRadars();
|
|
58
|
-
this._connectWebSocket();
|
|
60
|
+
if (!this.halted) this._connectWebSocket();
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
async destroy() {
|
|
@@ -77,7 +79,43 @@ class MayaraIngestor {
|
|
|
77
79
|
this._log("stop", { message: "ingestor destroyed" });
|
|
78
80
|
}
|
|
79
81
|
|
|
82
|
+
_halt(reason, details = {}) {
|
|
83
|
+
if (this.halted || this.destroyed) return;
|
|
84
|
+
this.halted = true;
|
|
85
|
+
this._log("halted", { reason, ...details });
|
|
86
|
+
|
|
87
|
+
if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
|
|
88
|
+
if (this.pollTimer) clearInterval(this.pollTimer);
|
|
89
|
+
this.reconnectTimer = null;
|
|
90
|
+
this.pollTimer = null;
|
|
91
|
+
|
|
92
|
+
if (this.ws) {
|
|
93
|
+
try {
|
|
94
|
+
this.ws.close();
|
|
95
|
+
} catch (err) {
|
|
96
|
+
this._log("ws_close_error", { error: err.message });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
this.ws = null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
_isServerUnreachable(err) {
|
|
103
|
+
if (!err) return false;
|
|
104
|
+
const message = String(err?.message || "").toLowerCase();
|
|
105
|
+
const code = String(err?.code || err?.cause?.code || "").toUpperCase();
|
|
106
|
+
return (
|
|
107
|
+
code === "ECONNREFUSED" ||
|
|
108
|
+
code === "ENOTFOUND" ||
|
|
109
|
+
code === "EHOSTUNREACH" ||
|
|
110
|
+
code === "ETIMEDOUT" ||
|
|
111
|
+
message.includes("fetch failed") ||
|
|
112
|
+
message.includes("connection refused") ||
|
|
113
|
+
message.includes("host unreachable")
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
80
117
|
async _discoverRadars() {
|
|
118
|
+
if (this.destroyed || this.halted) return;
|
|
81
119
|
this._log("discover", { message: "requesting radar list" });
|
|
82
120
|
try {
|
|
83
121
|
const res = await fetch(
|
|
@@ -102,6 +140,12 @@ class MayaraIngestor {
|
|
|
102
140
|
this._log("discover_ok", { radarCount: this.radarIds.length });
|
|
103
141
|
} catch (err) {
|
|
104
142
|
this._log("discover_error", { error: err.message });
|
|
143
|
+
if (this._isServerUnreachable(err)) {
|
|
144
|
+
this._halt("discover-unreachable", {
|
|
145
|
+
error: err.message,
|
|
146
|
+
code: err?.code || err?.cause?.code || null,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
105
149
|
}
|
|
106
150
|
}
|
|
107
151
|
|
|
@@ -114,7 +158,7 @@ class MayaraIngestor {
|
|
|
114
158
|
}
|
|
115
159
|
|
|
116
160
|
_connectWebSocket() {
|
|
117
|
-
if (this.destroyed) return;
|
|
161
|
+
if (this.destroyed || this.halted) return;
|
|
118
162
|
const wsUrl = this._buildWsUrl();
|
|
119
163
|
this._log("ws_connecting", { wsUrl });
|
|
120
164
|
|
|
@@ -138,12 +182,20 @@ class MayaraIngestor {
|
|
|
138
182
|
});
|
|
139
183
|
|
|
140
184
|
this.ws.on("message", (raw) => this._handleDelta(raw));
|
|
141
|
-
this.ws.on("error", (err) =>
|
|
185
|
+
this.ws.on("error", (err) => {
|
|
186
|
+
this._log("ws_error", { error: err.message });
|
|
187
|
+
if (this._isServerUnreachable(err)) {
|
|
188
|
+
this._halt("ws-unreachable", {
|
|
189
|
+
error: err.message,
|
|
190
|
+
code: err?.code || err?.cause?.code || null,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
});
|
|
142
194
|
this.ws.on("close", () => this._scheduleReconnect());
|
|
143
195
|
}
|
|
144
196
|
|
|
145
197
|
_scheduleReconnect() {
|
|
146
|
-
if (this.destroyed) return;
|
|
198
|
+
if (this.destroyed || this.halted) return;
|
|
147
199
|
this.wsFailCount += 1;
|
|
148
200
|
this._log(
|
|
149
201
|
"ws_close",
|
|
@@ -263,7 +315,7 @@ class MayaraIngestor {
|
|
|
263
315
|
}
|
|
264
316
|
|
|
265
317
|
_startHttpFallback() {
|
|
266
|
-
if (this.pollTimer || this.destroyed) return;
|
|
318
|
+
if (this.pollTimer || this.destroyed || this.halted) return;
|
|
267
319
|
this._log("http_fallback_start", { reason: "ws-unstable" });
|
|
268
320
|
this.pollTimer = setInterval(async () => {
|
|
269
321
|
if (this.destroyed) return;
|