Skip to content

Commit

Permalink
chore: Replace cursor.count with calls to countDocuments or `esti…
Browse files Browse the repository at this point in the history
…matedDocumentCount` (#33725)
  • Loading branch information
KevLehman authored and ricardogarim committed Oct 28, 2024
1 parent 5f5bce2 commit 4dbb662
Show file tree
Hide file tree
Showing 18 changed files with 149 additions and 23 deletions.
1 change: 0 additions & 1 deletion apps/meteor/app/livechat/server/lib/Helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,6 @@ export const dispatchInquiryQueued = async (inquiry: ILivechatInquiryRecord, age
return;
}

logger.debug(`Notifying ${await onlineAgents.count()} agents of new inquiry`);
const notificationUserName = v && (v.name || v.username);

for await (const agent of onlineAgents) {
Expand Down
10 changes: 9 additions & 1 deletion apps/meteor/app/livechat/server/lib/LivechatTyped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ class LivechatClass {
Livechat.logger.debug(`Fetching online bot agents for department ${department}`);
const botAgents = await Livechat.getBotAgents(department);
if (botAgents) {
const onlineBots = await botAgents.count();
const onlineBots = await Livechat.countBotAgents(department);
this.logger.debug(`Found ${onlineBots} online`);
if (onlineBots > 0) {
return true;
Expand Down Expand Up @@ -632,6 +632,14 @@ class LivechatClass {
return Users.findBotAgents();
}

private async countBotAgents(department?: string) {
if (department) {
return LivechatDepartmentAgents.countBotsForDepartment(department);
}

return Users.countBotAgents();
}

private async resolveChatTags(
room: IOmnichannelRoom,
options: CloseRoomParams['options'] = {},
Expand Down
1 change: 0 additions & 1 deletion apps/meteor/app/livechat/server/lib/QueueManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ export class QueueManager {
return;
}

logger.debug(`Notifying ${await onlineAgents.count()} agents of new inquiry`);
const notificationUserName = v && (v.name || v.username);

for await (const agent of onlineAgents) {
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/app/livechat/server/lib/analytics/dashboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,11 @@ const getConversationsMetricsAsync = async ({
language: user.language || settings.get('Language') || 'en',
})) || [];
const metrics = ['Total_conversations', 'Open_conversations', 'On_Hold_conversations', 'Total_messages'];
const visitorsCount = await LivechatVisitors.getVisitorsBetweenDate({
const visitorsCount = await LivechatVisitors.countVisitorsBetweenDate({
start: new Date(start),
end: new Date(end),
department: departmentId,
}).count();
});
return {
totalizers: [
...totalizers.filter((metric: { title: string }) => metrics.includes(metric.title)),
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/app/livechat/server/lib/departmentsLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,8 @@ export async function getRequiredDepartment(onlineRequired = true) {
return dept;
}

const onlineAgents = await LivechatDepartmentAgents.getOnlineForDepartment(dept._id);
if (onlineAgents && (await onlineAgents.count())) {
const onlineAgents = await LivechatDepartmentAgents.countOnlineForDepartment(dept._id);
if (onlineAgents) {
return dept;
}
}
Expand Down
22 changes: 11 additions & 11 deletions apps/meteor/app/statistics/server/lib/statistics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { log } from 'console';
import os from 'os';

import { Analytics, Team, VideoConf, Presence } from '@rocket.chat/core-services';
import type { IRoom, IStats } from '@rocket.chat/core-typings';
import type { IRoom, IStats, ISetting } from '@rocket.chat/core-typings';
import { UserStatus } from '@rocket.chat/core-typings';
import {
NotificationQueue,
Expand Down Expand Up @@ -92,7 +92,7 @@ export const statistics = {
};

// Version
const uniqueID = await Settings.findOne('uniqueID');
const uniqueID = await Settings.findOne<Pick<ISetting, 'createdAt'>>('uniqueID', { projection: { createdAt: 1 } });
statistics.uniqueId = settings.get('uniqueID');
if (uniqueID) {
statistics.installedAt = uniqueID.createdAt.toISOString();
Expand Down Expand Up @@ -520,7 +520,7 @@ export const statistics = {
);

statsPms.push(
NotificationQueue.col.estimatedDocumentCount().then((count) => {
NotificationQueue.estimatedDocumentCount().then((count) => {
statistics.pushQueue = count;
}),
);
Expand All @@ -546,27 +546,27 @@ export const statistics = {
statistics.messageAuditLoad = settings.get('Message_Auditing_Panel_Load_Count');
statistics.joinJitsiButton = settings.get('Jitsi_Click_To_Join_Count');
statistics.slashCommandsJitsi = settings.get('Jitsi_Start_SlashCommands_Count');
statistics.totalOTRRooms = await Rooms.findByCreatedOTR().count();
statistics.totalOTRRooms = await Rooms.countByCreatedOTR({ readPreference });
statistics.totalOTR = settings.get('OTR_Count');
statistics.totalBroadcastRooms = await Rooms.findByBroadcast().count();
statistics.totalBroadcastRooms = await Rooms.countByBroadcast({ readPreference });
statistics.totalTriggeredEmails = settings.get('Triggered_Emails_Count');
statistics.totalRoomsWithStarred = await Messages.countRoomsWithStarredMessages({ readPreference });
statistics.totalRoomsWithPinned = await Messages.countRoomsWithPinnedMessages({ readPreference });
statistics.totalUserTOTP = await Users.countActiveUsersTOTPEnable({ readPreference });
statistics.totalUserEmail2fa = await Users.countActiveUsersEmail2faEnable({ readPreference });
statistics.totalPinned = await Messages.findPinned({ readPreference }).count();
statistics.totalStarred = await Messages.findStarred({ readPreference }).count();
statistics.totalPinned = await Messages.countPinned({ readPreference });
statistics.totalStarred = await Messages.countStarred({ readPreference });
statistics.totalLinkInvitation = await Invites.estimatedDocumentCount();
statistics.totalLinkInvitationUses = await Invites.countUses();
statistics.totalEmailInvitation = settings.get('Invitation_Email_Count');
statistics.totalE2ERooms = await Rooms.findByE2E({ readPreference }).count();
statistics.totalE2ERooms = await Rooms.countByE2E({ readPreference });
statistics.logoChange = Object.keys(settings.get('Assets_logo') || {}).includes('url');
statistics.showHomeButton = settings.get('Layout_Show_Home_Button');
statistics.totalEncryptedMessages = await Messages.countByType('e2e', { readPreference });
statistics.totalManuallyAddedUsers = settings.get('Manual_Entry_User_Count');
statistics.totalSubscriptionRoles = await RolesRaw.findByScope('Subscriptions').count();
statistics.totalUserRoles = await RolesRaw.findByScope('Users').count();
statistics.totalCustomRoles = await RolesRaw.findCustomRoles({ readPreference }).count();
statistics.totalSubscriptionRoles = await RolesRaw.countByScope('Subscriptions', { readPreference });
statistics.totalUserRoles = await RolesRaw.countByScope('Users', { readPreference });
statistics.totalCustomRoles = await RolesRaw.countCustomRoles({ readPreference });
statistics.totalWebRTCCalls = settings.get('WebRTC_Calls_Count');
statistics.uncaughtExceptionsCount = settings.get('Uncaught_Exceptions_Count');

Expand Down
23 changes: 23 additions & 0 deletions apps/meteor/server/models/raw/LivechatDepartmentAgents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,19 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw<ILivechatDepartmentAgen
return this.find(query);
}

async countOnlineForDepartment(departmentId: string, isLivechatEnabledWhenAgentIdle?: boolean): Promise<number> {
const agents = await this.findByDepartmentId(departmentId, { projection: { username: 1 } }).toArray();

if (agents.length === 0) {
return 0;
}

return Users.countOnlineUserFromList(
agents.map((a) => a.username),
isLivechatEnabledWhenAgentIdle,
);
}

async getBotsForDepartment(departmentId: string): Promise<undefined | FindCursor<ILivechatDepartmentAgents>> {
const agents = await this.findByDepartmentId(departmentId).toArray();

Expand All @@ -287,6 +300,16 @@ export class LivechatDepartmentAgentsRaw extends BaseRaw<ILivechatDepartmentAgen
return this.find(query);
}

async countBotsForDepartment(departmentId: string): Promise<number> {
const agents = await this.findByDepartmentId(departmentId, { projection: { username: 1 } }).toArray();

if (agents.length === 0) {
return 0;
}

return Users.countBotAgents(agents.map((a) => a.username));
}

async getNextBotForDepartment(
departmentId: ILivechatDepartmentAgents['departmentId'],
ignoreAgentId?: ILivechatDepartmentAgents['agentId'],
Expand Down
4 changes: 2 additions & 2 deletions apps/meteor/server/models/raw/LivechatVisitors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export class LivechatVisitorsRaw extends BaseRaw<ILivechatVisitor> implements IL
return this.findOne(query, options);
}

getVisitorsBetweenDate({ start, end, department }: { start: Date; end: Date; department?: string }): FindCursor<ILivechatVisitor> {
countVisitorsBetweenDate({ start, end, department }: { start: Date; end: Date; department?: string }): Promise<number> {
const query = {
disabled: { $ne: true },
_updatedAt: {
Expand All @@ -115,7 +115,7 @@ export class LivechatVisitorsRaw extends BaseRaw<ILivechatVisitor> implements IL
...(department && department !== 'undefined' && { department }),
};

return this.find(query, { projection: { _id: 1 } });
return this.countDocuments(query);
}

async getNextVisitorUsername(): Promise<string> {
Expand Down
19 changes: 19 additions & 0 deletions apps/meteor/server/models/raw/Messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,16 @@ export class MessagesRaw extends BaseRaw<IMessage> implements IMessagesModel {
return this.find(query, options);
}

countPinned(options?: CountDocumentsOptions): Promise<number> {
const query: Filter<IMessage> = {
t: { $ne: 'rm' as MessageTypesValues },
_hidden: { $ne: true },
pinned: true,
};

return this.countDocuments(query, options);
}

findPaginatedPinnedByRoom(roomId: IMessage['rid'], options?: FindOptions<IMessage>): FindPaginated<FindCursor<IMessage>> {
const query: Filter<IMessage> = {
t: { $ne: 'rm' },
Expand All @@ -559,6 +569,15 @@ export class MessagesRaw extends BaseRaw<IMessage> implements IMessagesModel {
return this.find(query, options);
}

countStarred(options?: CountDocumentsOptions): Promise<number> {
const query: Filter<IMessage> = {
'_hidden': { $ne: true },
'starred._id': { $exists: true },
};

return this.countDocuments(query, options);
}

async setFederationReactionEventId(username: string, _id: string, reaction: string, federationEventId: string): Promise<void> {
await this.updateOne(
{ _id },
Expand Down
18 changes: 17 additions & 1 deletion apps/meteor/server/models/raw/Roles.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { IRole, IRoom, IUser, RocketChatRecordDeleted } from '@rocket.chat/core-typings';
import type { IRolesModel } from '@rocket.chat/model-typings';
import { Subscriptions, Users } from '@rocket.chat/models';
import type { Collection, FindCursor, Db, Filter, FindOptions, Document } from 'mongodb';
import type { Collection, FindCursor, Db, Filter, FindOptions, Document, CountDocumentsOptions } from 'mongodb';

import { notifyOnSubscriptionChangedByRoomIdAndUserId } from '../../../app/lib/server/lib/notifyListener';
import { BaseRaw } from './BaseRaw';
Expand Down Expand Up @@ -184,6 +184,14 @@ export class RolesRaw extends BaseRaw<IRole> implements IRolesModel {
return this.find(query, options || {});
}

countByScope(scope: IRole['scope'], options?: CountDocumentsOptions): Promise<number> {
const query = {
scope,
};

return this.countDocuments(query, options);
}

findCustomRoles(options?: FindOptions<IRole>): FindCursor<IRole> {
const query: Filter<IRole> = {
protected: false,
Expand All @@ -192,6 +200,14 @@ export class RolesRaw extends BaseRaw<IRole> implements IRolesModel {
return this.find(query, options || {});
}

countCustomRoles(options?: CountDocumentsOptions): Promise<number> {
const query: Filter<IRole> = {
protected: false,
};

return this.countDocuments(query, options || {});
}

async updateById(
_id: IRole['_id'],
name: IRole['name'],
Expand Down
23 changes: 23 additions & 0 deletions apps/meteor/server/models/raw/Rooms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import type {
UpdateOptions,
UpdateResult,
ModifyResult,
CountDocumentsOptions,
} from 'mongodb';

import { readSecondaryPreferred } from '../../database/readSecondaryPreferred';
Expand Down Expand Up @@ -654,6 +655,15 @@ export class RoomsRaw extends BaseRaw<IRoom> implements IRoomsModel {
);
}

countByBroadcast(options?: CountDocumentsOptions): Promise<number> {
return this.countDocuments(
{
broadcast: true,
},
options,
);
}

setAsFederated(roomId: IRoom['_id']): Promise<UpdateResult> {
return this.updateOne({ _id: roomId }, { $set: { federated: true } });
}
Expand Down Expand Up @@ -695,6 +705,15 @@ export class RoomsRaw extends BaseRaw<IRoom> implements IRoomsModel {
);
}

countByE2E(options?: CountDocumentsOptions): Promise<number> {
return this.countDocuments(
{
encrypted: true,
},
options,
);
}

findE2ERoomById(roomId: IRoom['_id'], options: FindOptions<IRoom> = {}): Promise<IRoom | null> {
return this.findOne(
{
Expand Down Expand Up @@ -1485,6 +1504,10 @@ export class RoomsRaw extends BaseRaw<IRoom> implements IRoomsModel {
return this.find({ createdOTR: true });
}

countByCreatedOTR(options?: CountDocumentsOptions): Promise<number> {
return this.countDocuments({ createdOTR: true }, options);
}

findByUsernamesOrUids(uids: IRoom['u']['_id'][], usernames: IRoom['u']['username'][]): FindCursor<IRoom> {
return this.find({ $or: [{ usernames: { $in: usernames } }, { uids: { $in: uids } }] });
}
Expand Down
27 changes: 27 additions & 0 deletions apps/meteor/server/models/raw/Users.js
Original file line number Diff line number Diff line change
Expand Up @@ -1449,6 +1449,17 @@ export class UsersRaw extends BaseRaw {
return this.find(query);
}

countOnlineUserFromList(userList, isLivechatEnabledWhenAgentIdle) {
// TODO: Create class Agent
const username = {
$in: [].concat(userList),
};

const query = queryStatusAgentOnline({ username }, isLivechatEnabledWhenAgentIdle);

return this.countDocuments(query);
}

findOneOnlineAgentByUserList(userList, options, isLivechatEnabledWhenAgentIdle) {
// TODO:: Create class Agent
const username = {
Expand Down Expand Up @@ -1480,6 +1491,22 @@ export class UsersRaw extends BaseRaw {
return this.find(query);
}

countBotAgents(usernameList) {
// TODO:: Create class Agent
const query = {
roles: {
$all: ['bot', 'livechat-agent'],
},
...(usernameList && {
username: {
$in: [].concat(usernameList),
},
}),
};

return this.countDocuments(query);
}

removeAllRoomsByUserId(_id) {
return this.updateOne(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ export interface ILivechatDepartmentAgentsModel extends IBaseModel<ILivechatDepa
departmentId: string,
isLivechatEnabledWhenAgentIdle?: boolean,
): Promise<FindCursor<ILivechatDepartmentAgents> | undefined>;
countOnlineForDepartment(departmentId: string, isLivechatEnabledWhenAgentIdle?: boolean): Promise<number>;
getBotsForDepartment(departmentId: string): Promise<undefined | FindCursor<ILivechatDepartmentAgents>>;
countBotsForDepartment(departmentId: string): Promise<number>;
getNextBotForDepartment(
departmentId: ILivechatDepartmentAgents['departmentId'],
ignoreAgentId?: ILivechatDepartmentAgents['agentId'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import type { FindPaginated, IBaseModel } from './IBaseModel';
export interface ILivechatVisitorsModel extends IBaseModel<ILivechatVisitor> {
findById(_id: string, options?: FindOptions<ILivechatVisitor>): FindCursor<ILivechatVisitor>;
getVisitorByToken(token: string, options?: FindOptions<ILivechatVisitor>): Promise<ILivechatVisitor | null>;
getVisitorsBetweenDate({ start, end, department }: { start: Date; end: Date; department?: string }): FindCursor<ILivechatVisitor>;
findByNameRegexWithExceptionsAndConditions<P extends Document = ILivechatVisitor>(
searchTerm: string,
exceptions: string[],
Expand Down Expand Up @@ -77,4 +76,5 @@ export interface ILivechatVisitorsModel extends IBaseModel<ILivechatVisitor> {
data: { name?: string; username?: string; email?: string; phone?: string; livechatData: { [k: string]: any } },
): Promise<UpdateResult | Document | boolean>;
setLastChatById(_id: string, lastChat: Required<ILivechatVisitor['lastChat']>): Promise<UpdateResult>;
countVisitorsBetweenDate({ start, end, department }: { start: Date; end: Date; department?: string }): Promise<number>;
}
2 changes: 2 additions & 0 deletions packages/model-typings/src/models/IMessagesModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,4 +291,6 @@ export interface IMessagesModel extends IBaseModel<IMessage> {

findThreadsByRoomId(rid: string, skip: number, limit: number): FindCursor<IMessage>;
decreaseReplyCountById(_id: string, inc?: number): Promise<UpdateResult>;
countPinned(options?: CountDocumentsOptions): Promise<number>;
countStarred(options?: CountDocumentsOptions): Promise<number>;
}
4 changes: 3 additions & 1 deletion packages/model-typings/src/models/IRolesModel.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IRole, IUser, IRoom } from '@rocket.chat/core-typings';
import type { FindCursor, FindOptions } from 'mongodb';
import type { FindCursor, FindOptions, CountDocumentsOptions } from 'mongodb';

import type { IBaseModel } from './IBaseModel';

Expand Down Expand Up @@ -62,4 +62,6 @@ export interface IRolesModel extends IBaseModel<IRole> {

canAddUserToRole(uid: IUser['_id'], roleId: IRole['_id'], scope?: IRoom['_id']): Promise<boolean>;
countUsersInRole(roleId: IRole['_id'], scope?: IRoom['_id']): Promise<number>;
countByScope(scope: IRole['scope'], options?: CountDocumentsOptions): Promise<number>;
countCustomRoles(options?: CountDocumentsOptions): Promise<number>;
}
Loading

0 comments on commit 4dbb662

Please sign in to comment.