fix(monitoring,remoteingress,web): Prune old metrics buckets periodically, clear metrics caches on shutdown, simplify edge disconnect handling, and optimize network view data updates

This commit is contained in:
2026-02-21 18:56:44 +00:00
parent 15da996e70
commit 82ce17a941
6 changed files with 34 additions and 25 deletions

View File

@@ -1,5 +1,14 @@
# Changelog
## 2026-02-21 - 7.4.2 - fix(monitoring,remoteingress,web)
Prune old metrics buckets periodically, clear metrics caches on shutdown, simplify edge disconnect handling, and optimize network view data updates
- Call pruneOldBuckets() each minute to proactively remove stale time-series buckets in MetricsManager
- Clear metricsCache, emailMinuteBuckets and dnsMinuteBuckets when MetricsManager stops to avoid stale state on shutdown
- On edgeDisconnected remove the edgeStatuses entry instead of mutating an existing record (more explicit cleanup)
- Remove unused traffic-timer variables and move requestsPerSec history updates from render() into updateNetworkData() to avoid unnecessary re-renders
- Optimize traffic data array updates by shifting in-place then reassigning arrays to preserve Lit reactivity and reduce intermediate allocations
## 2026-02-21 - 7.4.1 - fix(dcrouter)
replace console logging with structured logger, improve metrics logging, add terminal-ready wait in ops UI, bump dees-catalog patch

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@serve.zone/dcrouter',
version: '7.4.1',
version: '7.4.2',
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
}

View File

@@ -110,6 +110,9 @@ export class MetricsManager {
this.securityMetrics.incidents = [];
this.securityMetrics.lastResetDate = currentDate;
}
// Prune old time-series buckets every minute (don't wait for lazy query)
this.pruneOldBuckets();
}, 60000); // Check every minute
logger.log('info', 'MetricsManager started');
@@ -123,6 +126,12 @@ export class MetricsManager {
}
this.smartMetrics.stop();
// Clear caches and time-series buckets on shutdown
this.metricsCache.clear();
this.emailMinuteBuckets.clear();
this.dnsMinuteBuckets.clear();
logger.log('info', 'MetricsManager stopped');
}

View File

@@ -35,11 +35,7 @@ export class TunnelManager {
});
this.hub.on('edgeDisconnected', (data: { edgeId: string }) => {
const existing = this.edgeStatuses.get(data.edgeId);
if (existing) {
existing.connected = false;
existing.activeTunnels = 0;
}
this.edgeStatuses.delete(data.edgeId);
});
this.hub.on('streamOpened', (data: { edgeId: string; streamId: number }) => {

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@serve.zone/dcrouter',
version: '7.4.1',
version: '7.4.2',
description: 'A multifaceted routing service handling mail and SMS delivery functions.'
}

View File

@@ -47,9 +47,6 @@ export class OpsViewNetwork extends DeesElement {
private lastChartUpdate = 0;
private chartUpdateThreshold = 1000; // Minimum ms between chart updates
private lastTrafficUpdateTime = 0;
private trafficUpdateInterval = 1000; // Update every 1 second
private requestCountHistory = new Map<number, number>(); // Track requests per time bucket
private trafficUpdateTimer: any = null;
private requestsPerSecHistory: number[] = []; // Track requests/sec over time for trend
private historyLoaded = false; // Whether server-side throughput history has been loaded
@@ -106,8 +103,6 @@ export class OpsViewNetwork extends DeesElement {
this.trafficDataIn = [...emptyData];
this.trafficDataOut = emptyData.map(point => ({ ...point }));
this.lastTrafficUpdateTime = now;
}
/**
@@ -413,11 +408,7 @@ export class OpsViewNetwork extends DeesElement {
const throughput = this.calculateThroughput();
const activeConnections = this.statsState.serverStats?.activeConnections || 0;
// Track requests/sec history for the trend sparkline
this.requestsPerSecHistory.push(reqPerSec);
if (this.requestsPerSecHistory.length > 20) {
this.requestsPerSecHistory.shift();
}
// Build trend data from pre-computed history (mutated in updateNetworkData, not here)
const trendData = [...this.requestsPerSecHistory];
while (trendData.length < 20) {
trendData.unshift(0);
@@ -529,6 +520,13 @@ export class OpsViewNetwork extends DeesElement {
}
private async updateNetworkData() {
// Track requests/sec history for the trend sparkline (moved out of render)
const reqPerSec = this.networkState.requestsPerSecond || 0;
this.requestsPerSecHistory.push(reqPerSec);
if (this.requestsPerSecHistory.length > 20) {
this.requestsPerSecHistory.shift();
}
// Only update if connections changed significantly
const newConnectionCount = this.networkState.connections.length;
const oldConnectionCount = this.networkRequests.length;
@@ -602,16 +600,13 @@ export class OpsViewNetwork extends DeesElement {
y: Math.round(throughputOutMbps * 10) / 10
};
// Efficient array updates - modify in place when possible
// In-place mutation then reassign for Lit reactivity (avoids 4 intermediate arrays)
if (this.trafficDataIn.length >= 60) {
// Remove oldest and add newest
this.trafficDataIn = [...this.trafficDataIn.slice(1), newDataPointIn];
this.trafficDataOut = [...this.trafficDataOut.slice(1), newDataPointOut];
} else {
// Still filling up the initial data
this.trafficDataIn.shift();
this.trafficDataOut.shift();
}
this.trafficDataIn = [...this.trafficDataIn, newDataPointIn];
this.trafficDataOut = [...this.trafficDataOut, newDataPointOut];
}
this.lastChartUpdate = now;
}