diff --git a/changelog.md b/changelog.md index 3b6ef34..c0849b4 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,12 @@ # Changelog +## 2026-02-26 - 5.2.3 - fix(delivery) +prevent throttle reset timer from firing after stop and avoid scheduling duplicate timers + +- add throttleResetTimer property to track scheduled throttle-reset timeout +- clear throttleResetTimer when stopping to prevent it firing after shutdown +- clear existing throttleResetTimer before scheduling a new one and null it when fired to avoid duplicate timers and potential leaks + ## 2026-02-12 - 5.2.2 - fix(deps) bump dependencies: @push.rocks/smartrust to ^1.2.1, lru-cache to ^11.2.6 diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 65b6851..0176adb 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartmta', - version: '5.2.2', + version: '5.2.3', description: 'A high-performance, enterprise-grade Mail Transfer Agent (MTA) built from scratch in TypeScript with Rust acceleration.' } diff --git a/ts/mail/delivery/classes.delivery.system.ts b/ts/mail/delivery/classes.delivery.system.ts index 2d9c31f..4d2d21b 100644 --- a/ts/mail/delivery/classes.delivery.system.ts +++ b/ts/mail/delivery/classes.delivery.system.ts @@ -108,6 +108,7 @@ export class MultiModeDeliverySystem extends EventEmitter { private activeDeliveries: Set = new Set(); private running: boolean = false; private throttled: boolean = false; + private throttleResetTimer: ReturnType | null = null; private rateLimitLastCheck: number = Date.now(); private rateLimitCounter: number = 0; private emailServer?: UnifiedEmailServer; @@ -211,7 +212,13 @@ export class MultiModeDeliverySystem extends EventEmitter { } this.running = false; - + + // Clear throttle reset timer to prevent it firing after stop + if (this.throttleResetTimer) { + clearTimeout(this.throttleResetTimer); + this.throttleResetTimer = null; + } + // Wait for active deliveries to complete if (this.activeDeliveries.size > 0) { logger.log('info', `Waiting for ${this.activeDeliveries.size} active deliveries to complete`); @@ -776,7 +783,11 @@ export class MultiModeDeliverySystem extends EventEmitter { // Schedule throttle reset const resetDelay = 60000 - elapsed; - setTimeout(() => { + if (this.throttleResetTimer) { + clearTimeout(this.throttleResetTimer); + } + this.throttleResetTimer = setTimeout(() => { + this.throttleResetTimer = null; this.throttled = false; this.rateLimitLastCheck = Date.now(); this.rateLimitCounter = 0;