fix(zt-gateway): prevent health dots flashing red on each poll cycle
Cache last-known health state per region so renderGatewayRow uses correct values instead of defaulting to unreachable. Parallelize refreshHealth with Promise.all so all gateway pings resolve together instead of sequentially (3 gateways × -W 3 timeout was ~18s worst case).
This commit is contained in:
@@ -59,7 +59,8 @@ function ubusSetup(command) {
|
||||
return view.extend({
|
||||
state: {
|
||||
selectedRegion: null,
|
||||
switchMode: 'force'
|
||||
switchMode: 'force',
|
||||
healthCache: {}
|
||||
},
|
||||
|
||||
load() {
|
||||
@@ -87,11 +88,14 @@ return view.extend({
|
||||
change: ev => this.onSelectRegion(ev.target.value),
|
||||
checked: isSelected || null,
|
||||
})),
|
||||
E('td', { class: 'zt-region-cell' }, [
|
||||
this.renderHealthDot(false, null),
|
||||
' ',
|
||||
(() => {
|
||||
const cached = this.state.healthCache[gw.region];
|
||||
const dot = this.renderHealthDot(cached ? cached.reachable : false, cached ? cached.latency_ms : null);
|
||||
return E('td', { class: 'zt-region-cell' }, [
|
||||
dot, ' ',
|
||||
isActive ? E('strong', {}, gw.region) : document.createTextNode(gw.region)
|
||||
]),
|
||||
]);
|
||||
})(),
|
||||
E('td', {}, gw.label),
|
||||
E('td', {}, gw.ip),
|
||||
E('td', {}, isActive ? E('em', {}, _('active')) : '')
|
||||
@@ -250,25 +254,34 @@ return view.extend({
|
||||
|
||||
async refreshHealth(data) {
|
||||
const gws = data.gateways || [];
|
||||
for (let i = 0; i < gws.length; i++) {
|
||||
const region = gws[i].region;
|
||||
try {
|
||||
const h = await ubusHealth(region);
|
||||
const checks = gws.map(gw => {
|
||||
return ubusHealth(gw.region).then(h => {
|
||||
if (h) {
|
||||
this.state.healthCache[gw.region] = {
|
||||
reachable: !!h.reachable,
|
||||
latency_ms: h.latency_ms ?? null
|
||||
};
|
||||
}
|
||||
return { region: gw.region, h };
|
||||
}).catch(() => {
|
||||
this.state.healthCache[gw.region] = { reachable: false, latency_ms: null };
|
||||
return { region: gw.region, h: null };
|
||||
});
|
||||
});
|
||||
|
||||
const results = await Promise.all(checks);
|
||||
for (const { region, h } of results) {
|
||||
if (!h) continue;
|
||||
const row = document.querySelector('.zt-gateway-row[data-region="%s"]'.format(region));
|
||||
if (row && h) {
|
||||
if (!row) continue;
|
||||
const node = row.querySelector('.zt-health');
|
||||
if (node) {
|
||||
if (!node) continue;
|
||||
node.classList.toggle('zt-health-up', !!h.reachable);
|
||||
node.classList.toggle('zt-health-down', !h.reachable);
|
||||
node.title = h.reachable && h.latency_ms != null
|
||||
? _('UP (%sms)').format(h.latency_ms)
|
||||
: (h.reachable ? _('UP') : _('DOWN'));
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
/* health check is best-effort */
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
async refreshState() {
|
||||
|
||||
Reference in New Issue
Block a user