mirror of
https://github.com/PR0M3TH3AN/TORCH.git
synced 2026-11-06 12:51:54 +00:00
Merge pull request #289 from PR0M3TH3AN/optimize-relay-ranking-1239301882622685923
⚡ Optimize relay ranking with caching
This commit is contained in:
3 files changed
+176
-18
No files matched your search
+64
-18
@@ -205,6 +205,8 @@ export class RelayHealthManager {
|
||||
constructor() {
|
||||
this.metricsByRelay = new Map();
|
||||
this.lastSnapshotAt = 0;
|
||||
this._metricsVersion = 0;
|
||||
this._sortedCache = null;
|
||||
}
|
||||
|
||||
ensureMetrics(relay, config) {
|
||||
@@ -220,31 +222,72 @@ export class RelayHealthManager {
|
||||
lastResultAt: null,
|
||||
};
|
||||
this.metricsByRelay.set(relay, metrics);
|
||||
this._metricsVersion += 1;
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
rankRelays(relays, config, nowMs = Date.now()) {
|
||||
const summaries = relays.map((relay) => {
|
||||
const metrics = this.ensureMetrics(relay, config);
|
||||
const summary = summarizeRelayMetrics(metrics, nowMs);
|
||||
return {
|
||||
relay,
|
||||
summary,
|
||||
score: computeRelayScore(summary),
|
||||
};
|
||||
});
|
||||
for (const relay of relays) {
|
||||
this.ensureMetrics(relay, config);
|
||||
}
|
||||
|
||||
return summaries.sort((a, b) => {
|
||||
if (b.score !== a.score) return b.score - a.score;
|
||||
if (a.summary.quarantined !== b.summary.quarantined) return a.summary.quarantined ? 1 : -1;
|
||||
if (a.summary.averageLatencyMs !== b.summary.averageLatencyMs) {
|
||||
if (a.summary.averageLatencyMs === null) return 1;
|
||||
if (b.summary.averageLatencyMs === null) return -1;
|
||||
return a.summary.averageLatencyMs - b.summary.averageLatencyMs;
|
||||
if (
|
||||
!this._sortedCache
|
||||
|| this._sortedCache.version !== this._metricsVersion
|
||||
|| nowMs >= this._sortedCache.validUntil
|
||||
) {
|
||||
let minQuarantineUntil = Infinity;
|
||||
const entries = [];
|
||||
|
||||
for (const metrics of this.metricsByRelay.values()) {
|
||||
const summary = summarizeRelayMetrics(metrics, nowMs);
|
||||
const score = computeRelayScore(summary);
|
||||
if (metrics.quarantineUntil > nowMs && metrics.quarantineUntil < minQuarantineUntil) {
|
||||
minQuarantineUntil = metrics.quarantineUntil;
|
||||
}
|
||||
entries.push({
|
||||
relay: metrics.relay,
|
||||
summary,
|
||||
score,
|
||||
metrics,
|
||||
});
|
||||
}
|
||||
return a.relay.localeCompare(b.relay);
|
||||
});
|
||||
|
||||
entries.sort((a, b) => {
|
||||
if (b.score !== a.score) return b.score - a.score;
|
||||
if (a.summary.quarantined !== b.summary.quarantined) return a.summary.quarantined ? 1 : -1;
|
||||
if (a.summary.averageLatencyMs !== b.summary.averageLatencyMs) {
|
||||
if (a.summary.averageLatencyMs === null) return 1;
|
||||
if (b.summary.averageLatencyMs === null) return -1;
|
||||
return a.summary.averageLatencyMs - b.summary.averageLatencyMs;
|
||||
}
|
||||
return a.relay.localeCompare(b.relay);
|
||||
});
|
||||
|
||||
this._sortedCache = {
|
||||
version: this._metricsVersion,
|
||||
validUntil: minQuarantineUntil,
|
||||
entries,
|
||||
};
|
||||
}
|
||||
|
||||
const requestedSet = new Set(relays);
|
||||
return this._sortedCache.entries
|
||||
.filter((entry) => requestedSet.has(entry.relay))
|
||||
.map((entry) => {
|
||||
const quarantineRemainingMs = entry.metrics.quarantineUntil > nowMs
|
||||
? entry.metrics.quarantineUntil - nowMs
|
||||
: 0;
|
||||
return {
|
||||
relay: entry.relay,
|
||||
score: entry.score,
|
||||
summary: {
|
||||
...entry.summary,
|
||||
quarantineRemainingMs,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
prioritizeRelays(relays, config, nowMs = Date.now()) {
|
||||
@@ -292,6 +335,7 @@ export class RelayHealthManager {
|
||||
metrics.quarantineUntil = nowMs + metrics.cooldownMs;
|
||||
metrics.cooldownMs = Math.min(config.maxQuarantineCooldownMs, Math.floor(metrics.cooldownMs * 1.5));
|
||||
}
|
||||
this._metricsVersion += 1;
|
||||
}
|
||||
|
||||
collectSnapshot(relays, config, nowMs = Date.now()) {
|
||||
@@ -317,6 +361,8 @@ export class RelayHealthManager {
|
||||
reset() {
|
||||
this.metricsByRelay.clear();
|
||||
this.lastSnapshotAt = 0;
|
||||
this._metricsVersion = 0;
|
||||
this._sortedCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user