Initial proxy manager refactor

This commit is contained in:
Boki 2025-06-20 12:20:06 -04:00
parent 84cb14680b
commit da916222c1
6 changed files with 58 additions and 37 deletions

View file

@ -1,5 +1,5 @@
/**
* Proxy management utilities
*/
export { ProxyManager, proxyManager } from './proxy-manager';
export { default as ProxyManager } from './proxy-manager';
export type { ProxyInfo } from '@stock-bot/http'; // Re-export for convenience

View file

@ -9,12 +9,13 @@ import type { ProxyInfo } from '@stock-bot/http';
const logger = getLogger('proxy-manager');
export class ProxyManager {
private static instance: ProxyManager | null = null;
private cache: CacheProvider;
private proxies: ProxyInfo[] = [];
private lastUpdate: Date | null = null;
private isInitialized = false;
constructor() {
private constructor() {
const databaseConfig = getDatabaseConfig();
this.cache = createCache({
redisConfig: databaseConfig.dragonfly,
@ -25,9 +26,9 @@ export class ProxyManager {
}
/**
* Initialize the proxy manager - loads existing proxies from cache
* Internal initialization - loads existing proxies from cache
*/
async initialize(): Promise<void> {
private async initializeInternal(): Promise<void> {
if (this.isInitialized) {
return;
}
@ -47,17 +48,18 @@ export class ProxyManager {
}
/**
* Get a random working proxy from the available pool
* Get a random working proxy from the available pool (synchronous)
*/
async getRandomProxy(): Promise<ProxyInfo | null> {
getRandomProxy(): ProxyInfo | null {
// Ensure initialized
if (!this.isInitialized) {
await this.initialize();
throw new Error('ProxyManager not initialized');
}
// Load from cache if memory is empty
// Return null if no proxies available
if (this.proxies.length === 0) {
await this.loadFromCache();
logger.warn('No proxies available in memory');
return null;
}
// Filter for working proxies (not explicitly marked as non-working)
@ -96,15 +98,11 @@ export class ProxyManager {
}
/**
* Get all working proxies
* Get all working proxies (synchronous)
*/
async getWorkingProxies(): Promise<ProxyInfo[]> {
getWorkingProxies(): ProxyInfo[] {
if (!this.isInitialized) {
await this.initialize();
}
if (this.proxies.length === 0) {
await this.loadFromCache();
throw new Error('ProxyManager not initialized');
}
return this.proxies.filter(proxy => proxy.isWorking !== false);
@ -113,13 +111,9 @@ export class ProxyManager {
/**
* Get all proxies (working and non-working)
*/
async getAllProxies(): Promise<ProxyInfo[]> {
getAllProxies(): ProxyInfo[] {
if (!this.isInitialized) {
await this.initialize();
}
if (this.proxies.length === 0) {
await this.loadFromCache();
throw new Error('ProxyManager not initialized');
}
return [...this.proxies];
@ -250,7 +244,34 @@ export class ProxyManager {
logger.error('Failed to load proxies from cache', { error });
}
}
/**
* Initialize the singleton instance
*/
static async initialize(): Promise<void> {
if (!ProxyManager.instance) {
ProxyManager.instance = new ProxyManager();
await ProxyManager.instance.initializeInternal();
}
}
/**
* Get the singleton instance (must be initialized first)
*/
static getInstance(): ProxyManager {
if (!ProxyManager.instance) {
throw new Error('ProxyManager not initialized. Call ProxyManager.initialize() first.');
}
return ProxyManager.instance;
}
/**
* Reset the singleton instance (for testing)
*/
static reset(): void {
ProxyManager.instance = null;
}
}
// Singleton instance for easy import
export const proxyManager = new ProxyManager();
// Export the class as default
export default ProxyManager;