Properties and methods for monitoring pool state, capacity, and resource utilization, providing comprehensive visibility into pool performance and health metrics.
Monitor the pool's capacity and resource allocation limits.
/**
* Pool capacity properties (read-only)
*/
class Pool extends EventEmitter {
/** How many more resources can be created before hitting max limit */
readonly spareResourceCapacity: number;
/** Maximum number of resources allowed in the pool */
readonly max: number;
/** Minimum number of resources to maintain in the pool */
readonly min: number;
}Usage Examples:
// Monitor pool capacity
function logPoolCapacity() {
console.log(`Pool Capacity:`);
console.log(` Max resources: ${pool.max}`);
console.log(` Min resources: ${pool.min}`);
console.log(` Spare capacity: ${pool.spareResourceCapacity}`);
if (pool.spareResourceCapacity === 0) {
console.warn('Pool at maximum capacity!');
}
}
// Auto-scaling decision making
function shouldScale() {
const utilizationRate = (pool.max - pool.spareResourceCapacity) / pool.max;
return utilizationRate > 0.8; // Scale when 80% utilized
}
// Capacity alerts
setInterval(() => {
if (pool.spareResourceCapacity <= 2) {
console.warn(`Low pool capacity: only ${pool.spareResourceCapacity} resources can be created`);
}
}, 30000); // Check every 30 secondsMonitor the current state and distribution of resources in the pool.
/**
* Resource count properties (read-only)
*/
class Pool extends EventEmitter {
/** Total number of resources in the pool regardless of state */
readonly size: number;
/** Number of resources currently available for borrowing */
readonly available: number;
/** Number of resources currently borrowed by consumers */
readonly borrowed: number;
/** Number of pending resource requests waiting in the queue */
readonly pending: number;
}Usage Examples:
// Comprehensive pool status
function getPoolStatus() {
return {
totalResources: pool.size,
available: pool.available,
inUse: pool.borrowed,
waitingRequests: pool.pending,
utilizationPercent: Math.round((pool.borrowed / pool.size) * 100),
queueDepth: pool.pending
};
}
// Resource distribution analysis
function analyzeResourceDistribution() {
const total = pool.size;
const available = pool.available;
const borrowed = pool.borrowed;
const pending = pool.pending;
console.log(`Resource Distribution:`);
console.log(` Total: ${total}`);
console.log(` Available: ${available} (${Math.round(available/total*100)}%)`);
console.log(` Borrowed: ${borrowed} (${Math.round(borrowed/total*100)}%)`);
console.log(` Pending requests: ${pending}`);
// Health indicators
if (pending > borrowed) {
console.warn('Queue backup: more requests pending than resources in use');
}
if (available === 0 && borrowed < pool.max) {
console.info('All available resources in use, but pool can still grow');
}
}
// Performance monitoring
class PoolPerformanceMonitor {
constructor(pool) {
this.pool = pool;
this.samples = [];
this.startTime = Date.now();
}
takeSample() {
const sample = {
timestamp: Date.now(),
size: this.pool.size,
available: this.pool.available,
borrowed: this.pool.borrowed,
pending: this.pool.pending,
utilizationRate: this.pool.borrowed / this.pool.size
};
this.samples.push(sample);
// Keep only last 100 samples
if (this.samples.length > 100) {
this.samples.shift();
}
return sample;
}
getAverageUtilization(minutes = 5) {
const cutoff = Date.now() - (minutes * 60 * 1000);
const recentSamples = this.samples.filter(s => s.timestamp > cutoff);
if (recentSamples.length === 0) return 0;
const totalUtilization = recentSamples.reduce((sum, s) => sum + s.utilizationRate, 0);
return totalUtilization / recentSamples.length;
}
getPeakUsage() {
return this.samples.reduce((max, sample) =>
Math.max(max, sample.borrowed), 0
);
}
}Monitor pending resource requests and queue behavior.
Usage Examples:
// Queue depth monitoring
function monitorQueue() {
const queueDepth = pool.pending;
if (queueDepth > 0) {
console.log(`${queueDepth} requests waiting for resources`);
if (queueDepth > pool.max) {
console.warn('Queue depth exceeds pool capacity - consider increasing max pool size');
}
}
}
// Queue performance metrics
class QueueMetrics {
constructor(pool) {
this.pool = pool;
this.maxQueueDepth = 0;
this.queueEvents = [];
// Monitor queue changes
setInterval(() => {
const currentPending = pool.pending;
if (currentPending > this.maxQueueDepth) {
this.maxQueueDepth = currentPending;
}
this.queueEvents.push({
timestamp: Date.now(),
pending: currentPending,
available: pool.available
});
// Keep only last hour of events
const oneHourAgo = Date.now() - (60 * 60 * 1000);
this.queueEvents = this.queueEvents.filter(e => e.timestamp > oneHourAgo);
}, 1000);
}
getQueueStats() {
return {
currentPending: this.pool.pending,
maxQueueDepth: this.maxQueueDepth,
averageQueueDepth: this.getAverageQueueDepth(),
queueBlockageTime: this.getAverageBlockageTime()
};
}
getAverageQueueDepth() {
if (this.queueEvents.length === 0) return 0;
const total = this.queueEvents.reduce((sum, e) => sum + e.pending, 0);
return total / this.queueEvents.length;
}
getAverageBlockageTime() {
// Calculate average time when queue is blocked (pending > 0 but available = 0)
const blockedEvents = this.queueEvents.filter(e => e.pending > 0 && e.available === 0);
return (blockedEvents.length / this.queueEvents.length) * 100; // Percentage
}
}Integrate pool monitoring with health check systems and alerting.
Usage Examples:
// Health check endpoint
function poolHealthCheck() {
const status = getPoolStatus();
// Determine health status
let health = 'healthy';
const issues = [];
if (status.utilizationPercent > 90) {
health = 'warning';
issues.push('High utilization');
}
if (status.queueDepth > status.totalResources) {
health = 'critical';
issues.push('Queue backup');
}
if (status.available === 0 && status.inUse < pool.max) {
issues.push('Resource starvation');
}
return {
status: health,
issues,
metrics: status,
timestamp: new Date().toISOString()
};
}
// Monitoring dashboard data
function getDashboardMetrics() {
return {
pool: {
configuration: {
maxSize: pool.max,
minSize: pool.min,
currentSize: pool.size
},
utilization: {
total: pool.size,
available: pool.available,
borrowed: pool.borrowed,
utilizationPercent: Math.round((pool.borrowed / pool.size) * 100)
},
queue: {
pending: pool.pending,
capacity: pool.spareResourceCapacity
},
health: poolHealthCheck().status
}
};
}
// Alerting integration
class PoolAlerting {
constructor(pool, thresholds = {}) {
this.pool = pool;
this.thresholds = {
highUtilization: 85,
criticalUtilization: 95,
maxQueueDepth: 50,
...thresholds
};
this.alerts = [];
this.startMonitoring();
}
startMonitoring() {
setInterval(() => {
this.checkThresholds();
}, 10000); // Check every 10 seconds
}
checkThresholds() {
const utilization = (this.pool.borrowed / this.pool.size) * 100;
const queueDepth = this.pool.pending;
if (utilization > this.thresholds.criticalUtilization) {
this.raiseAlert('critical', `Pool utilization critical: ${utilization.toFixed(1)}%`);
} else if (utilization > this.thresholds.highUtilization) {
this.raiseAlert('warning', `Pool utilization high: ${utilization.toFixed(1)}%`);
}
if (queueDepth > this.thresholds.maxQueueDepth) {
this.raiseAlert('warning', `Queue depth excessive: ${queueDepth} pending requests`);
}
}
raiseAlert(level, message) {
const alert = {
level,
message,
timestamp: Date.now(),
poolStats: getPoolStatus()
};
this.alerts.push(alert);
console.log(`[${level.toUpperCase()}] ${message}`);
// Integrate with external alerting systems
this.sendToAlertingSystem(alert);
}
sendToAlertingSystem(alert) {
// Implementation depends on your alerting system
// e.g., send to Slack, PagerDuty, email, etc.
}
}Set up real-time monitoring and logging for continuous pool observation.
Usage Examples:
// Real-time pool monitor
class RealTimePoolMonitor {
constructor(pool, intervalMs = 5000) {
this.pool = pool;
this.interval = intervalMs;
this.monitoring = false;
}
start() {
if (this.monitoring) return;
this.monitoring = true;
this.monitoringInterval = setInterval(() => {
this.logPoolState();
}, this.interval);
console.log('Pool monitoring started');
}
stop() {
if (!this.monitoring) return;
clearInterval(this.monitoringInterval);
this.monitoring = false;
console.log('Pool monitoring stopped');
}
logPoolState() {
const timestamp = new Date().toISOString();
const stats = getPoolStatus();
console.log(`[${timestamp}] Pool Status:`, {
size: stats.totalResources,
available: stats.available,
borrowed: stats.inUse,
pending: stats.waitingRequests,
utilization: `${stats.utilizationPercent}%`
});
}
}
// Usage
const monitor = new RealTimePoolMonitor(pool, 10000); // Log every 10 seconds
monitor.start();
// Stop monitoring on shutdown
process.on('SIGTERM', () => {
monitor.stop();
});