Skip to content

Commit

Permalink
refactor: LivechatPriority out of DB Watcher (#32362)
Browse files Browse the repository at this point in the history
Co-authored-by: Diego Sampaio <8591547+sampaiodiego@users.noreply.github.com>
  • Loading branch information
ricardogarim and sampaiodiego committed May 16, 2024
1 parent 3ed5bda commit fb6d9eb
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 20 deletions.
14 changes: 14 additions & 0 deletions apps/meteor/app/lib/server/lib/notifyListener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,25 @@ import type {
IIntegration,
IPbxEvent,
LoginServiceConfiguration as LoginServiceConfigurationData,
ILivechatPriority,
} from '@rocket.chat/core-typings';
import { Rooms, Permissions, Settings, PbxEvents, Roles, Integrations, LoginServiceConfiguration } from '@rocket.chat/models';

type ClientAction = 'inserted' | 'updated' | 'removed';

export async function notifyOnLivechatPriorityChanged(
data: Pick<ILivechatPriority, 'name' | '_id'>,
clientAction: ClientAction = 'updated',
): Promise<void> {
if (!dbWatchersDisabled) {
return;
}

const { _id, ...rest } = data;

void api.broadcast('watch.priorities', { clientAction, id: _id, diff: { ...rest } });
}

export async function notifyOnRoomChanged<T extends IRocketChatRecord>(
data: T | T[],
clientAction: ClientAction = 'updated',
Expand Down
13 changes: 12 additions & 1 deletion apps/meteor/ee/app/livechat-enterprise/server/api/priorities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { isGETLivechatPrioritiesParams, isPUTLivechatPriority } from '@rocket.ch

import { API } from '../../../../../app/api/server';
import { getPaginationItems } from '../../../../../app/api/server/helpers/getPaginationItems';
import { notifyOnLivechatPriorityChanged } from '../../../../../app/lib/server/lib/notifyListener';
import { findPriority, updatePriority } from './lib/priorities';

API.v1.addRoute(
Expand Down Expand Up @@ -55,7 +56,11 @@ API.v1.addRoute(
},
async put() {
const { priorityId } = this.urlParams;

await updatePriority(priorityId, this.bodyParams);

void notifyOnLivechatPriorityChanged({ _id: priorityId, ...this.bodyParams });

return API.v1.success();
},
},
Expand All @@ -75,7 +80,13 @@ API.v1.addRoute(
if (!(await LivechatPriority.canResetPriorities())) {
return API.v1.failure();
}
await LivechatPriority.resetPriorities();

const eligiblePriorities = (await LivechatPriority.findByDirty().toArray()).map(({ _id }) => _id);

await LivechatPriority.resetPriorities(eligiblePriorities);

eligiblePriorities.forEach((_id) => notifyOnLivechatPriorityChanged({ _id, name: undefined }));

return API.v1.success();
},
async get() {
Expand Down
10 changes: 7 additions & 3 deletions apps/meteor/ee/server/models/raw/LivechatPriority.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { ILivechatPriority } from '@rocket.chat/core-typings';
import type { ILivechatPriorityModel } from '@rocket.chat/model-typings';
import { escapeRegExp } from '@rocket.chat/string-helpers';
import type { Db, UpdateFilter, ModifyResult, IndexDescription } from 'mongodb';
import type { Db, UpdateFilter, ModifyResult, IndexDescription, FindCursor } from 'mongodb';

import { BaseRaw } from '../../../../server/models/raw/BaseRaw';

Expand Down Expand Up @@ -48,12 +48,16 @@ export class LivechatPriorityRaw extends BaseRaw<ILivechatPriority> implements I
return this.findOne(query, options);
}

findByDirty(): FindCursor<Pick<ILivechatPriority, '_id'>> {
return this.find({ dirty: true }, { projection: { _id: 1 } });
}

async canResetPriorities(): Promise<boolean> {
return Boolean(await this.findOne({ dirty: true }, { projection: { _id: 1 } }));
}

async resetPriorities(): Promise<void> {
await this.updateMany({ dirty: true }, [{ $set: { dirty: false } }, { $unset: 'name' }]);
async resetPriorities(ids: ILivechatPriority['_id'][]): Promise<void> {
await this.updateMany({ _id: { $in: ids } }, [{ $set: { dirty: false } }, { $unset: 'name' }]);
}

async updatePriority(_id: string, reset: boolean, name?: string): Promise<ModifyResult<ILivechatPriority>> {
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/server/database/watchCollections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ export function getWatchCollections(): string[] {
IntegrationHistory.getCollectionName(),
EmailInbox.getCollectionName(),
Settings.getCollectionName(),
LivechatPriority.getCollectionName(),
Subscriptions.getCollectionName(),
];

Expand All @@ -49,6 +48,7 @@ export function getWatchCollections(): string[] {
collections.push(PbxEvents.getCollectionName());
collections.push(Integrations.getCollectionName());
collections.push(Permissions.getCollectionName());
collections.push(LivechatPriority.getCollectionName());
collections.push(LoginServiceConfiguration.getCollectionName());
}

Expand Down
9 changes: 2 additions & 7 deletions apps/meteor/server/modules/watchers/watchers.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -422,20 +422,15 @@ export function initWatchers(watcher: DatabaseWatcher, broadcast: BroadcastCallb
}
});

watcher.on<ILivechatPriority>(LivechatPriority.getCollectionName(), async ({ clientAction, id, data: eventData, diff }) => {
watcher.on<ILivechatPriority>(LivechatPriority.getCollectionName(), async ({ clientAction, id, diff }) => {
if (clientAction !== 'updated' || !diff || !('name' in diff)) {
// For now, we don't support this actions from happening
return;
}

const data = eventData ?? (await LivechatPriority.findOne({ _id: id }));
if (!data) {
return;
}

// This solves the problem of broadcasting, since now, watcher is the one in charge of doing it.
// What i don't like is the idea of giving more responsibilities to watcher, even when this works
void broadcast('watch.priorities', { clientAction, data, id, diff });
void broadcast('watch.priorities', { clientAction, id, diff });
});

watcherStarted = true;
Expand Down
7 changes: 1 addition & 6 deletions packages/core-services/src/events/Events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,12 +287,7 @@ export type EventSignatures = {
'watch.pbxevents'(data: { clientAction: ClientAction; data: Partial<IPbxEvent>; id: string }): void;
'connector.statuschanged'(enabled: boolean): void;
'federation.userRoleChanged'(update: Record<string, any>): void;
'watch.priorities'(data: {
clientAction: ClientAction;
data: Partial<ILivechatPriority>;
id: string;
diff?: Record<string, string>;
}): void;
'watch.priorities'(data: { clientAction: ClientAction; id: ILivechatPriority['_id']; diff?: Record<string, string> }): void;
'apps.added'(appId: string): void;
'apps.removed'(appId: string): void;
'apps.updated'(appId: string): void;
Expand Down
5 changes: 3 additions & 2 deletions packages/model-typings/src/models/ILivechatPriorityModel.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { ILivechatPriority } from '@rocket.chat/core-typings';
import type { ModifyResult } from 'mongodb';
import type { FindCursor, ModifyResult } from 'mongodb';

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

export interface ILivechatPriorityModel extends IBaseModel<ILivechatPriority> {
findOneByIdOrName(_idOrName: string, options?: any): Promise<ILivechatPriority | null>;
findOneNameUsingRegex(_idOrName: string, options?: any): Promise<ILivechatPriority | null>;
findByDirty(): FindCursor<Pick<ILivechatPriority, '_id'>>;
canResetPriorities(): Promise<boolean>;
resetPriorities(): Promise<void>;
resetPriorities(ids: ILivechatPriority['_id'][]): Promise<void>;
updatePriority(_id: string, reset: boolean, name?: string): Promise<ModifyResult<ILivechatPriority>>;
}

0 comments on commit fb6d9eb

Please sign in to comment.