-
Notifications
You must be signed in to change notification settings - Fork 13.1k
[FIX][ENTERPRISE] Race condition on Omnichannel queues #19352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIX][ENTERPRISE] Race condition on Omnichannel queues #19352
Conversation
Co-authored-by: Douglas Fabris <[email protected]>
| return this.findOne(query); | ||
| } | ||
|
|
||
| async getDistinctQueuedDepartments() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any reason to not use distinct from mongodb driver?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The initial implementation was using distinct, but since undefined value is ignored when passing any filter(such as { status: 'queued' }) then I opted for an aggregation.
I implemented the distinct method again and now I'm adding undefined as default.
Undefined= public queue(when the inquiry is not associated with any department)
| }, | ||
| nextQueue() { | ||
| if (!this.pool.length) { | ||
| this.pool = [...this.activeQueues]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are you not calling getActiveQueues here instead of having it being called every 5 seconds? I didn't understand the whole process after first look.. 😅
I think making it clear that the pool is being populated only if it is empty might help understanding the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, your suggestion is exactly how it was implemented :D
The point is that I was thinking about a small number of different queues, then the method will be called more often but since we're now running it sequentially, there's no problem calling it this way.
| }, | ||
| async getActiveQueues() { | ||
| // undefined = public queue(without department) | ||
| return [undefined].concat(await LivechatInquiry.getDistinctQueuedDepartments()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I couldn't think on a better approach yet, but having an undefined item is weird 😂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
definitely 🙃
That's the reason I was using aggregate to fetch the data rather than distinct.
Proposed changes
The issue happens when running the
Concurrent Chats limitfeature in a high-performance environment. Due to simultaneous and concurrent processes, the algorithm(Load Balancing) routes to agents more than the acceptable number of ongoing chats they can assist to.So, in order to avoid this issue, we're implementing a specific process that will handle the Omnichannel queue and will ensure that each process is running sequentially. Given that each department is considered a queue, we're racing all active queues(departments) that are present in the waiting queue to make sure the queue won't get stuck.
Let say all agents from a specific department are busy, we need to allow agents from other departments to assist the chats associated with departments they are part of.
In addition, an important improvement has been added to the code. Rather than reading the
roomcollection to get the number of ongoing chats per agent, the new version is going the read thesubscriptioncollection. This is another performance improvement since the subscriptions are ephemeral when it comes to Omnichannel chats.Issue(s)
How to test or reproduce
Waiting Queue FeatureandMax. Number of Chatssettingapi/v1/livechat/roomScreenshots
Types of changes
Checklist
Changelog
Further comments