- Add TIP Proxy Network (packages/proxy-agent): SOCKS5 proxy agent for residential IP bypass of CloudFront WAF blocks - Add /api/proxy/* routes: node registration, heartbeat, load balancing - Add image extraction to Flexoptix catalog scraper (GraphQL small_image) - Add image extraction to Optcore scraper (Playwright gallery img) - Fix Fluxlight price scraping (BigCommerce HTML structure: data-product-price-without-tax) - Add SmartOptics scraper (8 DWDM/coherent products, og:image extraction) - Fix findOrCreateScrapedTransceiver to update image_url for existing records - Add image backfill script (backfill-images.ts): 178 Flexoptix images added - Fix DB connection pool: max 5, idleTimeoutMillis 10s (was unlimited, caused >100 connections) - Add proxy.ts utility for scraper proxy rotation
51 lines
1020 B
TypeScript
51 lines
1020 B
TypeScript
/**
|
|
* Bandwidth tracker — monitors usage and enforces limits
|
|
*/
|
|
|
|
export interface BandwidthStats {
|
|
bytesProxied: number;
|
|
requestsProxied: number;
|
|
bytesLimitHard: number;
|
|
limitReached: boolean;
|
|
}
|
|
|
|
export class BandwidthTracker {
|
|
private bytesProxied = 0;
|
|
private requestsProxied = 0;
|
|
private readonly bytesLimit: number;
|
|
|
|
constructor(maxGb: number) {
|
|
this.bytesLimit = maxGb * 1024 * 1024 * 1024;
|
|
}
|
|
|
|
addBytes(n: number): void {
|
|
this.bytesProxied += n;
|
|
}
|
|
|
|
incrementRequests(): void {
|
|
this.requestsProxied++;
|
|
}
|
|
|
|
isLimitReached(): boolean {
|
|
return this.bytesProxied >= this.bytesLimit;
|
|
}
|
|
|
|
getStats(): BandwidthStats {
|
|
return {
|
|
bytesProxied: this.bytesProxied,
|
|
requestsProxied: this.requestsProxied,
|
|
bytesLimitHard: this.bytesLimit,
|
|
limitReached: this.isLimitReached(),
|
|
};
|
|
}
|
|
|
|
getUsedGb(): number {
|
|
return this.bytesProxied / (1024 * 1024 * 1024);
|
|
}
|
|
|
|
reset(): void {
|
|
this.bytesProxied = 0;
|
|
this.requestsProxied = 0;
|
|
}
|
|
}
|