Skip to content
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

[IMPROVE] Avoid using omnichannel-queue collection #25491

Merged
merged 23 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
3aec9ff
Avoid using omnichannel-queue collection
KevLehman May 12, 2022
18258b0
remove old collection files
KevLehman May 12, 2022
1fc3299
Avoid using omnichannel-queue collection
KevLehman May 12, 2022
16f121a
remove old collection files
KevLehman May 12, 2022
2c12d15
Merge branch 'develop' into improve/remove-omnichannel-queue-col
KevLehman Jun 1, 2022
6005591
Add migration and indexes
KevLehman Jun 1, 2022
b98ec88
Merge branch 'improve/remove-omnichannel-queue-col' of github.com:Roc…
KevLehman Jun 1, 2022
2ef6a58
add typing for defaultAgent on inquiry
KevLehman Jun 2, 2022
4dfe840
Merge branch 'develop' into improve/remove-omnichannel-queue-col
KevLehman Jun 2, 2022
d9865c1
Merge branch 'develop' into improve/remove-omnichannel-queue-col
KevLehman Jun 7, 2022
271d94c
oops
KevLehman Jun 7, 2022
7a7abc2
Merge branch 'develop' into improve/remove-omnichannel-queue-col
murtaza98 Jun 9, 2022
707eff5
Merge branch 'develop' into improve/remove-omnichannel-queue-col
KevLehman Jun 16, 2022
1969af6
Merge branch 'improve/remove-omnichannel-queue-col' of github.com:Roc…
KevLehman Jun 16, 2022
0d0986e
Merge branch 'develop' into improve/remove-omnichannel-queue-col
murtaza98 Jun 29, 2022
cb15688
Remove queue collection from new model definitions
murtaza98 Jun 29, 2022
55e12fe
revert changes on old migration
murtaza98 Jun 29, 2022
5eb9799
QA issue: Waiting queue not working with autoselection routing algo
murtaza98 Jun 29, 2022
78fb5ed
Re-add migration
murtaza98 Jun 29, 2022
bbfe701
Merge branch 'develop' into improve/remove-omnichannel-queue-col
KevLehman Jun 30, 2022
f09fc45
Re-remove collection
KevLehman Jun 30, 2022
8ed7702
Integrate changes from PR
KevLehman Jun 30, 2022
895a90e
Merge branch 'develop' into improve/remove-omnichannel-queue-col
murtaza98 Jul 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions apps/meteor/app/models/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import LivechatDepartmentAgents from './models/LivechatDepartmentAgents';
import LivechatRooms from './models/LivechatRooms';
import LivechatVisitors from './models/LivechatVisitors';
import LivechatInquiry from './models/LivechatInquiry';
import OmnichannelQueue from './models/OmnichannelQueue';
import ImportData from './models/ImportData';

export { AppsLogsModel } from './models/apps-logs-model';
Expand All @@ -38,6 +37,5 @@ export {
LivechatRooms,
LivechatVisitors,
LivechatInquiry,
OmnichannelQueue,
ImportData,
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
import { ILivechatInquiryRecord } from '@rocket.chat/core-typings';
import { FindOneOptions, Cursor, WriteOpResult, DeleteWriteOpResultObject } from 'mongodb';

import { Base } from './_Base';

export class LivechatInquiry extends Base {
Expand All @@ -12,17 +15,18 @@ export class LivechatInquiry extends Base {
this.tryEnsureIndex({ status: 1 }); // 'ready', 'queued', 'taken'
this.tryEnsureIndex({ queueOrder: 1, estimatedWaitingTimeQueue: 1, estimatedServiceTimeAt: 1 });
this.tryEnsureIndex({ 'v.token': 1, 'status': 1 }); // visitor token and status
this.tryEnsureIndex({ locked: 1, lockedAt: 1 }, { sparse: true }); // locked and lockedAt
murtaza98 marked this conversation as resolved.
Show resolved Hide resolved
}

findOneById(inquiryId) {
findOneById(inquiryId: string): ILivechatInquiryRecord {
return this.findOne({ _id: inquiryId });
}

findOneByRoomId(rid, options) {
findOneByRoomId(rid: string, options?: FindOneOptions<ILivechatInquiryRecord>): ILivechatInquiryRecord {
return this.findOne({ rid }, options);
}

getNextInquiryQueued(department) {
getNextInquiryQueued(department?: string): ILivechatInquiryRecord {
return this.findOne(
{
status: 'queued',
Expand All @@ -38,14 +42,14 @@ export class LivechatInquiry extends Base {
);
}

getQueuedInquiries(options) {
getQueuedInquiries(options?: FindOneOptions<ILivechatInquiryRecord>): Cursor<ILivechatInquiryRecord> {
return this.find({ status: 'queued' }, options);
}

/*
* mark the inquiry as taken
*/
takeInquiry(inquiryId) {
takeInquiry(inquiryId: string): void {
this.update(
{
_id: inquiryId,
Expand All @@ -60,7 +64,7 @@ export class LivechatInquiry extends Base {
/*
* mark inquiry as open
*/
openInquiry(inquiryId) {
openInquiry(inquiryId: string): WriteOpResult {
return this.update(
{
_id: inquiryId,
Expand All @@ -74,7 +78,7 @@ export class LivechatInquiry extends Base {
/*
* mark inquiry as queued
*/
queueInquiry(inquiryId) {
queueInquiry(inquiryId: string): WriteOpResult {
return this.update(
{
_id: inquiryId,
Expand All @@ -86,7 +90,7 @@ export class LivechatInquiry extends Base {
);
}

queueInquiryAndRemoveDefaultAgent(inquiryId) {
queueInquiryAndRemoveDefaultAgent(inquiryId: string): WriteOpResult {
return this.update(
{
_id: inquiryId,
Expand All @@ -101,7 +105,7 @@ export class LivechatInquiry extends Base {
/*
* mark inquiry as ready
*/
readyInquiry(inquiryId) {
readyInquiry(inquiryId: string): WriteOpResult {
return this.update(
{
_id: inquiryId,
Expand All @@ -114,27 +118,27 @@ export class LivechatInquiry extends Base {
);
}

changeDepartmentIdByRoomId(rid, department) {
changeDepartmentIdByRoomId(rid: string, department: string): void {
const query = {
rid,
};
const update = {
const updateObj = {
$set: {
department,
},
};

this.update(query, update);
this.update(query, updateObj);
}

/*
* return the status of the inquiry (open or taken)
*/
getStatus(inquiryId) {
getStatus(inquiryId: string): ILivechatInquiryRecord['status'] {
return this.findOne({ _id: inquiryId }).status;
}

updateVisitorStatus(token, status) {
updateVisitorStatus(token: string, status: string): WriteOpResult {
const query = {
'v.token': token,
'status': 'queued',
Expand All @@ -149,7 +153,7 @@ export class LivechatInquiry extends Base {
return this.update(query, update);
}

setDefaultAgentById(inquiryId, defaultAgent) {
setDefaultAgentById(inquiryId: string, defaultAgent: ILivechatInquiryRecord['defaultAgent']): WriteOpResult {
return this.update(
{
_id: inquiryId,
Expand All @@ -162,7 +166,7 @@ export class LivechatInquiry extends Base {
);
}

setNameByRoomId(rid, name) {
setNameByRoomId(rid: string, name: string): WriteOpResult {
const query = { rid };

const update = {
Expand All @@ -173,15 +177,21 @@ export class LivechatInquiry extends Base {
return this.update(query, update);
}

findOneByToken(token) {
findOneByToken(token: string): ILivechatInquiryRecord {
const query = {
'v.token': token,
'status': 'queued',
};
return this.findOne(query);
}

async getCurrentSortedQueueAsync({ _id, department }) {
async getCurrentSortedQueueAsync({
_id,
department,
}: {
_id: string;
department: string;
}): Promise<Pick<ILivechatInquiryRecord, '_id' | 'rid' | 'name' | 'ts' | 'status' | 'department'> & { position: number }> {
const collectionObj = this.model.rawCollection();
const aggregate = [
{
Expand Down Expand Up @@ -227,7 +237,7 @@ export class LivechatInquiry extends Base {
position: 1,
},
},
];
] as any[];

// To get the current room position in the queue, we need to apply the next $match after the $project
if (_id) {
Expand All @@ -237,7 +247,7 @@ export class LivechatInquiry extends Base {
return collectionObj.aggregate(aggregate).toArray();
}

removeDefaultAgentById(inquiryId) {
removeDefaultAgentById(inquiryId: string): WriteOpResult {
return this.update(
{
_id: inquiryId,
Expand All @@ -251,54 +261,17 @@ export class LivechatInquiry extends Base {
/*
* remove the inquiry by roomId
*/
removeByRoomId(rid) {
removeByRoomId(rid: string): DeleteWriteOpResultObject {
return this.remove({ rid });
}

removeByVisitorToken(token) {
removeByVisitorToken(token: string): void {
const query = {
'v.token': token,
};

this.remove(query);
}

getUnnatendedQueueItems(date) {
const query = {
status: 'queued',
estimatedInactivityCloseTimeAt: { $lte: new Date(date) },
};
return this.find(query);
}

setEstimatedInactivityCloseTime(_id, date) {
return this.update(
{ _id },
{
$set: {
estimatedInactivityCloseTimeAt: new Date(date),
},
},
);
}

// This is a better solution, but update pipelines are not supported until version 4.2 of mongo
// leaving this here for when the time comes
/* updateEstimatedInactivityCloseTime(milisecondsToAdd) {
return this.model.rawCollection().updateMany(
{ status: 'queued' },
[{
// in case this field doesn't exists, set at the last time the item was modified (updatedAt)
$set: { estimatedInactivityCloseTimeAt: '$_updatedAt' },
}, {
$set: {
estimatedInactivityCloseTimeAt: {
$add: ['$estimatedInactivityCloseTimeAt', milisecondsToAdd],
},
},
}],
);
} */
}

export default new LivechatInquiry();
9 changes: 0 additions & 9 deletions apps/meteor/app/models/server/models/OmnichannelQueue.js

This file was deleted.

45 changes: 45 additions & 0 deletions apps/meteor/app/models/server/raw/LivechatInquiry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,49 @@ export class LivechatInquiryRaw extends BaseRaw<ILivechatInquiryRecord> {
async setLastMessageByRoomId(rid: string, message: IMessage): Promise<UpdateWriteOpResult> {
return this.updateOne({ rid }, { $set: { lastMessage: message } });
}

async findNextAndLock(queue?: string): Promise<ILivechatInquiryRecord | undefined> {
const date = new Date();
const result = await this.col.findOneAndUpdate(
{
status: LivechatInquiryStatus.QUEUED,
...(queue && { queue }),
$or: [
{
locked: true,
lockedAt: {
murtaza98 marked this conversation as resolved.
Show resolved Hide resolved
$lte: new Date(date.getTime() - 5000),
},
},
{
locked: false,
},
],
},
{
$set: {
locked: true,
// apply 5 secs lock lifetime
lockedAt: new Date(),
},
},
{
sort: {
queueOrder: 1,
estimatedWaitingTimeQueue: 1,
estimatedServiceTimeAt: 1,
},
},
);

return result.value;
}

async unlock(inquiryId: string): Promise<UpdateWriteOpResult> {
return this.updateOne({ _id: inquiryId }, { $unset: { locked: 1, lockedAt: 1 } });
}

async unlockAll(): Promise<UpdateWriteOpResult> {
return this.updateMany({}, { $unset: { locked: 1, lockedAt: 1 } });
}
}
Loading