1.0.0 โข Published 5 months ago
@bcoders.gr/virtualpool v1.0.0
@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
npm install @bcoders.gr/virtualpoolQuick Start
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
new AnvilProviderPool(portStart, portEnd, options)Parameters:
portStart(number): Starting port for Anvil instancesportEnd(number): Ending port for Anvil instancesoptions(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 functionproviderOptions(object): Options passed to IPCProvider
Methods
initialize()
Initialize all providers in the pool.
await pool.initialize();withProvider(fn)
Execute a function with an automatically managed provider.
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.
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.
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).
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.
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.
await pool.shutdown(10000); // 10 second force timeoutEvents
The pool emits various events for monitoring:
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
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
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
// 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:
npm run test:basic # Basic functionality
npm run test:comprehensive # Full test suite
npm run test:getavailable # Provider allocation testsRequirements
- Node.js >= 16.0.0
- Foundry with Anvil installed
- Linux/macOS (Windows support via WSL)
License
MIT License - see LICENSE file for details.
Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Support
- GitHub Issues: Report bugs or request features
- Documentation: Full API documentation
Built with โค๏ธ by bcoders.gr
1.0.0
5 months ago