Refactor: Fix Event Buffer Deadlock with State Machine (#1633)
* feat: implement state machine for chat synchronization and buffer management * test: Add Jest configuration and tests for connection deadlock handling - Created a Jest configuration file to set up testing environment. - Implemented utility functions for creating isolated authentication sessions and mocking WebSocket connections. - Added a test case to ensure that the connection does not deadlock when history sync is disabled, verifying the correct handling of message events. * feat: add GitHub Actions workflow for running tests * chore: sort import lint * fix: implement timeout handling for AwaitingInitialSync state in chat socket, maybe fix memory leak * feat: enhance chat synchronization by refining AwaitingInitialSync handling and adding history sync checks
This commit is contained in:
committed by
GitHub
parent
1a721bb242
commit
812e53e4eb
+14
-22
@@ -56,10 +56,9 @@ type BaileysBufferableEventEmitter = BaileysEventEmitter & {
|
||||
createBufferedFunction<A extends any[], T>(work: (...args: A) => Promise<T>): (...args: A) => Promise<T>
|
||||
/**
|
||||
* flushes all buffered events
|
||||
* @param force if true, will flush all data regardless of any pending buffers
|
||||
* @returns returns true if the flush actually happened, otherwise false
|
||||
*/
|
||||
flush(force?: boolean): boolean
|
||||
flush(): boolean
|
||||
/** is there an ongoing buffer */
|
||||
isBuffering(): boolean
|
||||
}
|
||||
@@ -74,7 +73,7 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
const historyCache = new Set<string>()
|
||||
|
||||
let data = makeBufferData()
|
||||
let buffersInProgress = 0
|
||||
let isBuffering = false
|
||||
|
||||
// take the generic event and fire it as a baileys event
|
||||
ev.on('event', (map: BaileysEventData) => {
|
||||
@@ -84,28 +83,22 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
})
|
||||
|
||||
function buffer() {
|
||||
buffersInProgress += 1
|
||||
if (!isBuffering) {
|
||||
logger.info('Event buffer activated')
|
||||
isBuffering = true
|
||||
}
|
||||
}
|
||||
|
||||
function flush(force = false) {
|
||||
// no buffer going on
|
||||
if (!buffersInProgress) {
|
||||
function flush() {
|
||||
if (!isBuffering) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!force) {
|
||||
// reduce the number of buffers in progress
|
||||
buffersInProgress -= 1
|
||||
// if there are still some buffers going on
|
||||
// then we don't flush now
|
||||
if (buffersInProgress) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
logger.info('Flushing event buffer')
|
||||
isBuffering = false
|
||||
|
||||
const newData = makeBufferData()
|
||||
const chatUpdates = Object.values(data.chatUpdates)
|
||||
// gather the remaining conditional events so we re-queue them
|
||||
let conditionalChatUpdatesLeft = 0
|
||||
for (const update of chatUpdates) {
|
||||
if (update.conditional) {
|
||||
@@ -139,7 +132,7 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
}
|
||||
},
|
||||
emit<T extends BaileysEvent>(event: BaileysEvent, evData: BaileysEventMap[T]) {
|
||||
if (buffersInProgress && BUFFERABLE_EVENT_SET.has(event)) {
|
||||
if (isBuffering && BUFFERABLE_EVENT_SET.has(event)) {
|
||||
append(data, historyCache, event as BufferableEvent, evData, logger)
|
||||
return true
|
||||
}
|
||||
@@ -147,7 +140,7 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
return ev.emit('event', { [event]: evData })
|
||||
},
|
||||
isBuffering() {
|
||||
return buffersInProgress > 0
|
||||
return isBuffering
|
||||
},
|
||||
buffer,
|
||||
flush,
|
||||
@@ -155,10 +148,9 @@ export const makeEventBuffer = (logger: ILogger): BaileysBufferableEventEmitter
|
||||
return async (...args) => {
|
||||
buffer()
|
||||
try {
|
||||
const result = await work(...args)
|
||||
return result
|
||||
return await work(...args)
|
||||
} finally {
|
||||
flush()
|
||||
// Flushing is now controlled centrally by the state machine.
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user