UNPKG

@bcoders.gr/virtualpool

Version:

Advanced Ethereum testing framework with provider pooling, load balancing, and comprehensive monitoring

258 lines (196 loc) โ€ข 6.77 kB
# @bcoders.gr/virtualpool Advanced Ethereum testing framework with provider pooling, load balancing, and comprehensive monitoring. ## Features - ๐Ÿš€ **Provider Pooling**: Manage multiple Anvil instances efficiently - โš–๏ธ **Load Balancing**: Multiple strategies (random, round-robin, least-used, fastest) - ๐Ÿ“Š **Monitoring**: Comprehensive metrics and health checks - ๐Ÿ”„ **Auto-recovery**: Automatic provider restart on failure - ๐ŸŽฏ **Circuit Breaker**: Prevent cascading failures - ๐Ÿงช **Testing Ready**: Built for extensive blockchain testing ## Installation ```bash npm install @bcoders.gr/virtualpool ``` ## Quick Start ```javascript import AnvilProviderPool from '@bcoders.gr/virtualpool'; // Create a pool with 3 providers on ports 8545-8547 const pool = new AnvilProviderPool(8545, 8547, { timeout: 30000, maxRetries: 5, healthCheckInterval: 30000 }); // Initialize the pool await pool.initialize(); // Use a provider with automatic management const blockNumber = await pool.withProvider(async (provider) => { return await provider.send('eth_blockNumber', []); }); console.log(`Current block: ${parseInt(blockNumber, 16)}`); // Shutdown when done await pool.shutdown(); ``` ## API Reference ### Constructor ```javascript new AnvilProviderPool(portStart, portEnd, options) ``` **Parameters:** - `portStart` (number): Starting port for Anvil instances - `portEnd` (number): Ending port for Anvil instances - `options` (object): Configuration options **Options:** - `timeout` (number): Provider startup timeout (default: 30000ms) - `maxRetries` (number): Max retry attempts (default: 5) - `maxRetriesPerPort` (number): Max retries per port (default: 3) - `healthCheckInterval` (number): Health check interval (default: 30000ms) - `anvilPath` (string): Path to anvil binary (default: '/root/.foundry/bin/anvil') - `maxParallelStarts` (number): Max parallel provider starts (default: 5) - `waitInterval` (number): Wait interval for provider availability (default: 10ms) - `gracefulShutdownTimeout` (number): Graceful shutdown timeout (default: 5000ms) - `logger` (function): Custom logger function - `providerOptions` (object): Options passed to IPCProvider ### Methods #### `initialize()` Initialize all providers in the pool. ```javascript await pool.initialize(); ``` #### `withProvider(fn)` Execute a function with an automatically managed provider. ```javascript const result = await pool.withProvider(async (provider) => { return await provider.send('eth_getBalance', [address, 'latest']); }); ``` #### `withProviderWait(fn, timeoutMs)` Execute a function with a provider, waiting if none available. ```javascript const result = await pool.withProviderWait(async (provider) => { return await provider.send('eth_call', [transaction, 'latest']); }, 10000); ``` #### `withProviderStrategy(fn, strategy, timeoutMs)` Execute a function using a specific load balancing strategy. ```javascript const result = await pool.withProviderStrategy(async (provider) => { return await provider.send('eth_chainId', []); }, 'roundRobin'); ``` **Strategies:** - `'random'`: Random provider selection (default) - `'roundRobin'`: Round-robin selection - `'leastUsed'`: Select least used provider - `'fastest'`: Select fastest responding provider #### `getAvailableProvider()` Get an available provider manually (for advanced use cases). ```javascript const providerInfo = pool.getAvailableProvider(); if (providerInfo) { const { provider, port } = providerInfo; // Use provider... pool.releaseProvider(port); // Don't forget to release! } ``` #### `getStats()` Get comprehensive pool statistics. ```javascript const stats = pool.getStats(); console.log(`Available: ${stats.available}/${stats.total}`); console.log(`Success rate: ${stats.successRate}`); console.log(`Avg response time: ${stats.averageResponseTime}ms`); ``` #### `shutdown(forceTimeout)` Gracefully shutdown the pool. ```javascript await pool.shutdown(10000); // 10 second force timeout ``` ## Events The pool emits various events for monitoring: ```javascript pool.on('requestCompleted', ({ port, responseTime, success }) => { console.log(`Request on port ${port}: ${responseTime}ms, success: ${success}`); }); pool.on('providerFailed', ({ port, error }) => { console.log(`Provider ${port} failed: ${error}`); }); pool.on('providerRecovered', ({ port }) => { console.log(`Provider ${port} recovered`); }); pool.on('healthCheckCompleted', (stats) => { console.log(`Health check completed, ${stats.healthy} healthy providers`); }); ``` ## Advanced Usage ### Custom Configuration ```javascript const pool = new AnvilProviderPool(8545, 8549, { timeout: 60000, maxRetries: 10, healthCheckInterval: 60000, logger: (msg) => console.log(`[POOL] ${msg}`), providerOptions: { requestTimeout: 30000, autoReconnect: true } }); ``` ### Error Handling ```javascript try { await pool.initialize(); } catch (error) { console.error('Failed to initialize pool:', error.message); // Handle initialization failure } try { const result = await pool.withProvider(async (provider) => { return await provider.send('eth_getTransactionReceipt', [txHash]); }); } catch (error) { console.error('Transaction failed:', error.message); // Handle request failure } ``` ### Monitoring ```javascript // Regular stats monitoring setInterval(() => { const stats = pool.getStats(); console.log(`Pool utilization: ${stats.utilizationRate}`); console.log(`Requests/sec: ${stats.requestsPerSecond}`); }, 10000); // Event-based monitoring pool.on('requestCompleted', ({ port, responseTime, success, totalRequests }) => { if (!success) { console.warn(`Failed request on port ${port}`); } if (totalRequests % 1000 === 0) { console.log(`Processed ${totalRequests} requests`); } }); ``` ## Testing The package includes comprehensive tests: ```bash npm run test:basic # Basic functionality npm run test:comprehensive # Full test suite npm run test:getavailable # Provider allocation tests ``` ## Requirements - Node.js >= 16.0.0 - [Foundry](https://getfoundry.sh/) with Anvil installed - Linux/macOS (Windows support via WSL) ## License MIT License - see [LICENSE](LICENSE) file for details. ## Contributing 1. Fork the repository 2. Create a feature branch 3. Add tests for new functionality 4. Ensure all tests pass 5. Submit a pull request ## Support - GitHub Issues: [Report bugs or request features](https://github.com/pagovitsa/virtualpool/issues) - Documentation: [Full API documentation](https://github.com/pagovitsa/virtualpool/wiki) --- Built with โค๏ธ by [bcoders.gr](https://bcoders.gr)