Fix critical memory leak in event buffer (#2160)
This commit is contained in:
@@ -74,6 +74,7 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
let data = makeBufferData()
|
||||
let isBuffering = false
|
||||
let bufferTimeout: NodeJS.Timeout | null = null
|
||||
let flushPendingTimeout: NodeJS.Timeout | null = null // Add a specific timer for the debounced flush to prevent leak
|
||||
let bufferCount = 0
|
||||
const MAX_HISTORY_CACHE_SIZE = 10000 // Limit the history cache size to prevent memory bloat
|
||||
const BUFFER_TIMEOUT_MS = 30000 // 30 seconds
|
||||
@@ -89,9 +90,8 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
if (!isBuffering) {
|
||||
logger.debug('Event buffer activated')
|
||||
isBuffering = true
|
||||
bufferCount++
|
||||
bufferCount = 0
|
||||
|
||||
// Auto-flush after a timeout to prevent infinite buffering
|
||||
if (bufferTimeout) {
|
||||
clearTimeout(bufferTimeout)
|
||||
}
|
||||
@@ -102,9 +102,10 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
flush()
|
||||
}
|
||||
}, BUFFER_TIMEOUT_MS)
|
||||
} else {
|
||||
bufferCount++
|
||||
}
|
||||
|
||||
// Always increment count when requested
|
||||
bufferCount++
|
||||
}
|
||||
|
||||
function flush() {
|
||||
@@ -122,6 +123,11 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
bufferTimeout = null
|
||||
}
|
||||
|
||||
if (flushPendingTimeout) {
|
||||
clearTimeout(flushPendingTimeout)
|
||||
flushPendingTimeout = null
|
||||
}
|
||||
|
||||
// Clear history cache if it exceeds the max size
|
||||
if (historyCache.size > MAX_HISTORY_CACHE_SIZE) {
|
||||
logger.debug({ cacheSize: historyCache.size }, 'Clearing history cache')
|
||||
@@ -217,8 +223,10 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
} finally {
|
||||
bufferCount = Math.max(0, bufferCount - 1)
|
||||
if (bufferCount === 0) {
|
||||
// Auto-flush when no other buffers are active
|
||||
setTimeout(flush, 100)
|
||||
// Only schedule ONE timeout, not 10,000
|
||||
if (!flushPendingTimeout) {
|
||||
flushPendingTimeout = setTimeout(flush, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user