perf: stability and performance improvements across proxy

- Add exponential backoff (200ms-2s) between retry attempts
- Fix session retry bug: rotate proxy before retry to avoid same proxy
- Fix ACTIVE_READERS memory leak: release reader on stream done/error
- Make closeAllActiveReaders async with proper await
- WebSocket backpressure: pause upstream forwarding at 512KB buffer
- Optimize rate-limiter pruneTimestamps: avoid array reallocation
- Batch stream chunks (8 per yield) to reduce event loop overhead
- Add periodic cooldown cleanup in ProxyPool (30s interval)
- Extract shared wrapStreamWithCleanup utility to reduce duplication
- Fix fetchViaCurl temp file cleanup with proper unlink()
- Add missing ipv6Source overload to AI proxy handlers
This commit is contained in:
MythEclipse
2026-06-20 19:32:23 +07:00
parent c62de0899a
commit ac19f8f30d
6 changed files with 250 additions and 150 deletions
+22
View File
@@ -41,6 +41,8 @@ export class ProxyPool {
/** host:port::model -> expiry epoch ms */
private cooldowns = new Map<string, number>();
private cooldownDuration = 60000; // default 60s
/** Periodic cleanup timer for expired cooldowns */
private cleanupTimer: ReturnType<typeof setInterval> | null = null;
// -- Load --------------------------------------------------------------------
@@ -126,9 +128,29 @@ export class ProxyPool {
this.currentIndex = 0;
this.failures.clear();
// Start periodic cooldown cleanup (every 30s)
this.startCooldownCleanup();
logPool(`loaded ${this.proxies.length} proxies from ${source}`);
}
/** Periodically clean up expired cooldown entries to prevent memory leaks. */
private startCooldownCleanup(): void {
if (this.cleanupTimer) return;
this.cleanupTimer = setInterval(() => {
const now = Date.now();
for (const [key, expiry] of this.cooldowns) {
if (now > expiry) {
this.cooldowns.delete(key);
}
}
}, 30_000); // every 30s
// Allow process to exit even if timer is active
if (this.cleanupTimer && typeof this.cleanupTimer === "object" && "unref" in this.cleanupTimer) {
this.cleanupTimer.unref();
}
}
/**
* Convenience -- load from a path or skip.
* Returns `true` if proxies were loaded.