From b3db9436b68033bb68e970b6c3c8ed1710e74639 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Thu, 26 Sep 2024 19:34:24 -0300 Subject: [PATCH 1/3] fix: split operations to prevent race condition --- apps/meteor/server/models/raw/BaseRaw.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/meteor/server/models/raw/BaseRaw.ts b/apps/meteor/server/models/raw/BaseRaw.ts index d822038b177e..3e763017bbd3 100644 --- a/apps/meteor/server/models/raw/BaseRaw.ts +++ b/apps/meteor/server/models/raw/BaseRaw.ts @@ -318,33 +318,33 @@ export abstract class BaseRaw< async findOneAndDelete(filter: Filter, options?: FindOneAndDeleteOptions): Promise> { if (!this.trash) { - if (options) { - return this.col.findOneAndDelete(filter, options); - } - return this.col.findOneAndDelete(filter); + return this.col.findOneAndDelete(filter, options || {}); } - const result = await this.col.findOneAndDelete(filter); - - const { value: doc } = result; + const doc = await this.col.findOne(filter); if (!doc) { - return result; + return { ok: 1, value: null }; } const { _id, ...record } = doc; - const trash: TDeleted = { ...record, _deletedAt: new Date(), __collection__: this.name, } as unknown as TDeleted; - // since the operation is not atomic, we need to make sure that the record is not already deleted/inserted await this.trash?.updateOne({ _id } as Filter, { $set: trash } as UpdateFilter, { upsert: true, }); - return result; + try { + await this.col.deleteOne({ _id } as Filter); + } catch (e) { + await this.trash?.deleteOne({ _id } as Filter); + throw e; + } + + return { ok: 1, value: doc }; } async deleteMany(filter: Filter, options?: DeleteOptions & { onTrash?: (record: ResultFields) => void }): Promise { From 997bcb4c5c342ff1037f8620e9a20dd1d579b857 Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 27 Sep 2024 08:39:50 -0300 Subject: [PATCH 2/3] add changeset --- .changeset/dry-taxis-cry.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/dry-taxis-cry.md diff --git a/.changeset/dry-taxis-cry.md b/.changeset/dry-taxis-cry.md new file mode 100644 index 000000000000..b77eaa7c15c4 --- /dev/null +++ b/.changeset/dry-taxis-cry.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/meteor': patch +--- + +Adjusts the findOneAndDelete method to insert into the trash collection before deletion to prevent a race condition that causes livechat users to get stuck in the agent's sidebar panel after being forwarded. From 56d3cbfe21a734a04b48a589454d91cb9db414fc Mon Sep 17 00:00:00 2001 From: Ricardo Garim Date: Fri, 27 Sep 2024 13:56:17 -0300 Subject: [PATCH 3/3] update changeset --- .changeset/dry-taxis-cry.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/dry-taxis-cry.md b/.changeset/dry-taxis-cry.md index b77eaa7c15c4..ae8244087d9e 100644 --- a/.changeset/dry-taxis-cry.md +++ b/.changeset/dry-taxis-cry.md @@ -2,4 +2,4 @@ '@rocket.chat/meteor': patch --- -Adjusts the findOneAndDelete method to insert into the trash collection before deletion to prevent a race condition that causes livechat users to get stuck in the agent's sidebar panel after being forwarded. +Fixes a race condition that causes livechat conversations to get stuck in the agent's sidebar panel after being forwarded.