From 2f769726dda4789e3b155816498d2093769f883a Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Fri, 12 Mar 2021 17:02:25 +0100 Subject: [PATCH] matrix-sdk: prevent dupplicated members requests --- matrix_sdk/src/client.rs | 15 +++++++------- matrix_sdk/src/room/common.rs | 38 +++++++++++++++++++++++++++-------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index 0639a635..0b7d06c5 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -88,16 +88,15 @@ use matrix_sdk_common::{ }; #[cfg(feature = "encryption")] -use matrix_sdk_common::{ - api::r0::{ - keys::{get_keys, upload_keys, upload_signing_keys::Request as UploadSigningKeysRequest}, - to_device::send_event_to_device::{ - Request as RumaToDeviceRequest, Response as ToDeviceResponse, - }, +use matrix_sdk_common::api::r0::{ + keys::{get_keys, upload_keys, upload_signing_keys::Request as UploadSigningKeysRequest}, + to_device::send_event_to_device::{ + Request as RumaToDeviceRequest, Response as ToDeviceResponse, }, - locks::Mutex, }; +use matrix_sdk_common::locks::Mutex; + use crate::{ error::HttpError, http_client::{client_with_config, HttpClient, HttpSend}, @@ -138,6 +137,7 @@ pub struct Client { #[cfg(feature = "encryption")] /// Lock making sure we're only doing one key claim request at a time. key_claim_lock: Arc>, + pub(crate) members_request_locks: DashMap>>, } #[cfg(not(tarpaulin_include))] @@ -393,6 +393,7 @@ impl Client { group_session_locks: DashMap::new(), #[cfg(feature = "encryption")] key_claim_lock: Arc::new(Mutex::new(())), + members_request_locks: DashMap::new(), }) } diff --git a/matrix_sdk/src/room/common.rs b/matrix_sdk/src/room/common.rs index aa4fd222..2a3fa773 100644 --- a/matrix_sdk/src/room/common.rs +++ b/matrix_sdk/src/room/common.rs @@ -2,7 +2,9 @@ use matrix_sdk_common::api::r0::{ membership::{get_member_events, join_room_by_id, leave_room}, message::get_message_events, }; -use std::ops::Deref; +use matrix_sdk_common::locks::Mutex; + +use std::{ops::Deref, sync::Arc}; use crate::{Client, Result, Room, RoomMember}; @@ -96,14 +98,34 @@ impl Common { } pub(crate) async fn request_members(&self) -> Result<()> { - // TODO: don't send a request if a request is being sent - let request = get_member_events::Request::new(self.inner.room_id()); - let response = self.client.send(request, None).await?; + #[allow(clippy::map_clone)] + if let Some(mutex) = self + .client + .members_request_locks + .get(self.inner.room_id()) + .map(|m| m.clone()) + { + mutex.lock().await; + } else { + let mutex = Arc::new(Mutex::new(())); + self.client + .members_request_locks + .insert(self.inner.room_id().clone(), mutex.clone()); - self.client - .base_client - .receive_members(self.inner.room_id(), &response) - .await?; + let _guard = mutex.lock().await; + + let request = get_member_events::Request::new(self.inner.room_id()); + let response = self.client.send(request, None).await?; + + self.client + .base_client + .receive_members(self.inner.room_id(), &response) + .await?; + + self.client + .members_request_locks + .remove(self.inner.room_id()); + } Ok(()) }