Keep 5-second delay between renders to withstand message floods
Instead of rendering the message list every time a message comes in, we give a delay of 5 seconds. If more messages have arrived in the meantime, those messages will also get included in the render. 5 seconds is selected to offer the best performance; if it ends up being too long we could later make it configurable or bring it down to something like 1 second. Another option is to intelligently ramp up the delays as messages flood in, and then ramp it down when the flow reduces to just 1-2 messages. But all that is for another day ;) This commit hopefully addresses #10; it should theoretically work but I haven't been able to fully test it yet due to not yet receiving a full flood of messages :P
This commit is contained in:
parent
8d1ca787fa
commit
1f7ad1408c
|
@ -43,27 +43,64 @@
|
|||
}
|
||||
}), 1000)
|
||||
|
||||
// Stores information on the rendered chatboxes
|
||||
let chatboxes = []
|
||||
let chatboxesRenderedAt = 0 // a very, very long time ago
|
||||
let chatboxesRendering = false // is a rendering scheduled?
|
||||
|
||||
// TODO: use a sliding window so that only the chatboxes
|
||||
// that are in view get rendered
|
||||
|
||||
// Helper function to convert chatboxes into
|
||||
// (exceedingly lightweight) object array for
|
||||
// final rendering
|
||||
function chatboxesToArray(chatboxes) {
|
||||
if (!chatboxes) return []
|
||||
|
||||
return _converse.chatboxes.models.map(c => ({
|
||||
return chatboxes.models.map(c => ({
|
||||
id: c.id,
|
||||
title: c.attributes.name || c.attributes.id,
|
||||
lastMessage: c.messages?.last()?.attributes?.body,
|
||||
}))
|
||||
}
|
||||
|
||||
let chatboxes = chatboxesToArray(_converse?.chatboxes)
|
||||
function renderChatboxes() {
|
||||
|
||||
// If the chatboxes are empty, just render an empty array
|
||||
if (!_converse?.chatboxes) {
|
||||
chatboxes = []
|
||||
return
|
||||
}
|
||||
|
||||
// If the chatboxes were updated more than 5 seconds ago,
|
||||
// render them again immediately
|
||||
if (new Date() - chatboxesRenderedAt > 5000) {
|
||||
chatboxes = chatboxesToArray(_converse?.chatboxes)
|
||||
} else {
|
||||
// If they were updated less than 5 seconds ago, check
|
||||
// if a re-render has been scheduled
|
||||
if (chatboxesRendering) {
|
||||
return
|
||||
} else {
|
||||
chatboxesRendering = true
|
||||
|
||||
// Render them after a gap
|
||||
setTimeout(function () {
|
||||
chatboxesRendering = false
|
||||
chatboxesRenderedAt = new Date()
|
||||
renderChatboxes()
|
||||
}, 5000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render them once
|
||||
renderChatboxes()
|
||||
|
||||
_converse.on('chatBoxesFetched', () => {
|
||||
chatboxes = chatboxesToArray(_converse.chatboxes)
|
||||
renderChatboxes()
|
||||
})
|
||||
|
||||
_converse.on('message', () => {
|
||||
chatboxes = chatboxesToArray(_converse.chatboxes)
|
||||
renderChatboxes()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
|
Loading…
Reference in a new issue