You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

144 lines
4.4 KiB

/**
* Outbox pressure management with telemetry
*/
import { OutboxPressureConfig, TelemetryMetrics } from './types';
import { DEFAULT_CONFIG } from './constants';
export class OutboxPressureManager {
private config: OutboxPressureConfig;
private metrics: TelemetryMetrics;
constructor(config: Partial<OutboxPressureConfig> = {}) {
this.config = {
maxUndelivered: config.maxUndelivered ?? DEFAULT_CONFIG.maxUndelivered,
cleanupIntervalMs: config.cleanupIntervalMs ?? DEFAULT_CONFIG.cleanupIntervalMs,
backpressureThreshold: config.backpressureThreshold ?? DEFAULT_CONFIG.backpressureThreshold,
evictionPolicy: config.evictionPolicy ?? 'fifo'
};
this.metrics = {
'starred_projects_outbox_size': 0,
'starred_projects_outbox_backpressure_active': 0
} as TelemetryMetrics;
}
async checkStoragePressure(undeliveredCount: number): Promise<boolean> {
// Update metrics
this.metrics['starred_projects_outbox_size'] = undeliveredCount;
const pressureRatio = undeliveredCount / this.config.maxUndelivered;
const backpressureActive = pressureRatio >= this.config.backpressureThreshold;
// Update backpressure metric
this.metrics['starred_projects_outbox_backpressure_active'] = backpressureActive ? 1 : 0;
if (pressureRatio >= 1.0) {
// Critical: Drop oldest notifications to make room
const evictCount = undeliveredCount - this.config.maxUndelivered;
await this.evictNotifications(evictCount);
return true; // Backpressure active
}
return backpressureActive;
}
async evictNotifications(count: number): Promise<void> {
if (count <= 0) return;
// Simulate eviction based on policy
switch (this.config.evictionPolicy) {
case 'fifo':
await this.evictFIFO(count);
break;
case 'lifo':
await this.evictLIFO(count);
break;
case 'priority':
await this.evictByPriority(count);
break;
}
}
private async evictFIFO(count: number): Promise<void> {
// Simulate: DELETE FROM notification_outbox
// WHERE delivered_at IS NULL
// ORDER BY created_at ASC
// LIMIT count
console.log(`Evicting ${count} oldest notifications (FIFO)`);
}
private async evictLIFO(count: number): Promise<void> {
// Simulate: DELETE FROM notification_outbox
// WHERE delivered_at IS NULL
// ORDER BY created_at DESC
// LIMIT count
console.log(`Evicting ${count} newest notifications (LIFO)`);
}
private async evictByPriority(count: number): Promise<void> {
// Simulate: DELETE FROM notification_outbox
// WHERE delivered_at IS NULL
// ORDER BY priority ASC, created_at ASC
// LIMIT count
console.log(`Evicting ${count} lowest priority notifications`);
}
async cleanupDeliveredNotifications(): Promise<void> {
// Simulate: DELETE FROM notification_outbox
// WHERE delivered_at IS NOT NULL
// AND delivered_at < datetime('now', '-${cleanupIntervalMs / 1000} seconds')
console.log(`Cleaning up delivered notifications older than ${this.config.cleanupIntervalMs}ms`);
}
getMetrics(): TelemetryMetrics {
return { ...this.metrics };
}
getConfig(): OutboxPressureConfig {
return { ...this.config };
}
}
/**
* Create default outbox pressure manager
*/
export function createDefaultOutboxPressureManager(): OutboxPressureManager {
return new OutboxPressureManager();
}
/**
* Create outbox pressure manager with custom config
*/
export function createOutboxPressureManager(config: Partial<OutboxPressureConfig>): OutboxPressureManager {
return new OutboxPressureManager(config);
}
/**
* Outbox pressure configuration presets
*/
export const OUTBOX_PRESSURE_PRESETS = {
// Conservative: Low memory usage, frequent cleanup
conservative: {
maxUndelivered: 500,
backpressureThreshold: 0.7,
cleanupIntervalMs: 1800000, // 30 minutes
evictionPolicy: 'fifo' as const
},
// Balanced: Good performance, reasonable memory usage
balanced: {
maxUndelivered: 1000,
backpressureThreshold: 0.8,
cleanupIntervalMs: 3600000, // 1 hour
evictionPolicy: 'fifo' as const
},
// Aggressive: High throughput, more memory usage
aggressive: {
maxUndelivered: 2000,
backpressureThreshold: 0.9,
cleanupIntervalMs: 7200000, // 2 hours
evictionPolicy: 'priority' as const
}
} as const;