@@ -70,7 +70,7 @@ pub enum SpaceRoomListPaginationState {
7070/// .await;
7171///
7272/// // Start off with an empty and idle list
73- /// room_list.rooms().is_empty();
73+ /// room_list.rooms().await. is_empty();
7474///
7575/// assert_eq!(
7676/// room_list.pagination_state(),
@@ -82,7 +82,7 @@ pub enum SpaceRoomListPaginationState {
8282/// room_list.subscribe_to_pagination_state_updates();
8383///
8484/// // And to room list updates
85- /// let (_, room_stream) = room_list.subscribe_to_room_updates();
85+ /// let (_, room_stream) = room_list.subscribe_to_room_updates().await ;
8686///
8787/// // Run this in a background task so it doesn't block
8888/// while let Some(pagination_state) = pagination_state_stream.next().await {
@@ -98,7 +98,7 @@ pub enum SpaceRoomListPaginationState {
9898/// room_list.paginate().await.unwrap();
9999///
100100/// // And, if successful, rooms are available
101- /// let rooms = room_list.rooms();
101+ /// let rooms = room_list.await. rooms();
102102/// # anyhow::Ok(()) };
103103/// ```
104104pub struct SpaceRoomList {
@@ -114,7 +114,7 @@ pub struct SpaceRoomList {
114114
115115 pagination_state : SharedObservable < SpaceRoomListPaginationState > ,
116116
117- rooms : Arc < Mutex < ObservableVector < SpaceRoom > > > ,
117+ rooms : Arc < AsyncMutex < ObservableVector < SpaceRoom > > > ,
118118
119119 _space_update_handle : Option < BackgroundTaskHandle > ,
120120
@@ -124,7 +124,7 @@ pub struct SpaceRoomList {
124124impl SpaceRoomList {
125125 /// Creates a new `SpaceRoomList` for the given space identifier.
126126 pub async fn new ( client : Client , space_id : OwnedRoomId ) -> Self {
127- let rooms = Arc :: new ( Mutex :: new ( ObservableVector :: < SpaceRoom > :: new ( ) ) ) ;
127+ let rooms = Arc :: new ( AsyncMutex :: new ( ObservableVector :: < SpaceRoom > :: new ( ) ) ) ;
128128
129129 let all_room_updates_receiver = client. subscribe_to_all_room_updates ( ) ;
130130
@@ -144,35 +144,25 @@ impl SpaceRoomList {
144144 continue ;
145145 }
146146
147- // Given the MutexGuard used by `rooms`, we need to drop any
148- // possible guard before calling `.await`, otherwise the compiler
149- // will complain.
150- let mut rooms_to_update_with_index = Vec :: new ( ) ;
151- {
152- let mutable_rooms = rooms. lock ( ) ;
153- for updated_room_id in updates. iter_all_room_ids ( ) {
154- if let Some ( ( position, room) ) = mutable_rooms
155- . iter ( )
156- . find_position ( |room| & room. room_id == updated_room_id)
157- {
158- rooms_to_update_with_index
159- . push ( ( position, room. clone ( ) ) ) ;
160- }
147+ let mut mutable_rooms = rooms. lock ( ) . await ;
148+
149+ for updated_room_id in updates. iter_all_room_ids ( ) {
150+ if let Some ( ( position, room) ) = mutable_rooms
151+ . clone ( )
152+ . iter ( )
153+ . find_position ( |room| & room. room_id == updated_room_id)
154+ && let Some ( updated_room) = client. get_room ( updated_room_id)
155+ {
156+ mutable_rooms. set (
157+ position,
158+ SpaceRoom :: new_from_known (
159+ & updated_room,
160+ room. children_count ,
161+ )
162+ . await ,
163+ ) ;
161164 }
162165 }
163-
164- for ( idx, room) in rooms_to_update_with_index {
165- let Some ( updated_room) = client. get_room ( & room. room_id ) else {
166- continue ;
167- } ;
168- let space_room = SpaceRoom :: new_from_known (
169- & updated_room,
170- room. children_count ,
171- )
172- . await ;
173- let mut mutable_rooms = rooms. lock ( ) ;
174- mutable_rooms. set ( idx, space_room) ;
175- }
176166 }
177167 Err ( err) => {
178168 error ! ( "error when listening to room updates: {err}" ) ;
@@ -258,15 +248,15 @@ impl SpaceRoomList {
258248 }
259249
260250 /// Return the current list of rooms.
261- pub fn rooms ( & self ) -> Vec < SpaceRoom > {
262- self . rooms . lock ( ) . iter ( ) . cloned ( ) . collect_vec ( )
251+ pub async fn rooms ( & self ) -> Vec < SpaceRoom > {
252+ self . rooms . lock ( ) . await . iter ( ) . cloned ( ) . collect_vec ( )
263253 }
264254
265255 /// Subscribes to room list updates.
266- pub fn subscribe_to_room_updates (
256+ pub async fn subscribe_to_room_updates (
267257 & self ,
268258 ) -> ( Vector < SpaceRoom > , VectorSubscriberBatchedStream < SpaceRoom > ) {
269- self . rooms . lock ( ) . subscribe ( ) . into_values_and_batched_stream ( )
259+ self . rooms . lock ( ) . await . subscribe ( ) . into_values_and_batched_stream ( )
270260 }
271261
272262 /// Ask the list to retrieve the next page if the end hasn't been reached
@@ -340,10 +330,9 @@ impl SpaceRoomList {
340330 }
341331
342332 let children_state = ( * self . children_state . lock ( ) ) . clone ( ) . unwrap_or_default ( ) ;
333+ let mut rooms = self . rooms . lock ( ) . await ;
343334
344- // Because of the `MutexGuard` used by `SpaceRoomList::rooms`, we need to
345- // perform all calls that involve `.await` before acquiring the lock.
346- let children_space_rooms = join_all ( children. into_iter ( ) . map ( |room| {
335+ join_all ( children. into_iter ( ) . map ( |room| {
347336 let children_state = children_state. clone ( ) ;
348337 async move {
349338 let child_state = children_state. get ( & room. summary . room_id ) ;
@@ -361,13 +350,10 @@ impl SpaceRoomList {
361350 . await
362351 }
363352 } ) )
364- . await ;
365-
366- let mut rooms = self . rooms . lock ( ) ;
367- children_space_rooms
368- . into_iter ( )
369- . sorted_by ( |a, b| Self :: compare_rooms ( a, b, & children_state) )
370- . for_each ( |room| rooms. push_back ( room) ) ;
353+ . await
354+ . into_iter ( )
355+ . sorted_by ( |a, b| Self :: compare_rooms ( a, b, & children_state) )
356+ . for_each ( |room| rooms. push_back ( room) ) ;
371357
372358 self . pagination_state . set ( SpaceRoomListPaginationState :: Idle {
373359 end_reached : result. next_batch . is_none ( ) ,
@@ -395,7 +381,7 @@ impl SpaceRoomList {
395381 let mut pagination_token = self . token . lock ( ) . await ;
396382 * pagination_token = None . into ( ) ;
397383
398- self . rooms . lock ( ) . clear ( ) ;
384+ self . rooms . lock ( ) . await . clear ( ) ;
399385 self . children_state . lock ( ) . take ( ) ;
400386
401387 self . pagination_state . set ( SpaceRoomListPaginationState :: Idle { end_reached : false } ) ;
@@ -488,15 +474,15 @@ mod tests {
488474 ) ;
489475
490476 // without any rooms
491- assert_eq ! ( room_list. rooms( ) , vec![ ] ) ;
477+ assert_eq ! ( room_list. rooms( ) . await , vec![ ] ) ;
492478
493479 // and with pending subscribers
494480
495481 let pagination_state_subscriber = room_list. subscribe_to_pagination_state_updates ( ) ;
496482 pin_mut ! ( pagination_state_subscriber) ;
497483 assert_pending ! ( pagination_state_subscriber) ;
498484
499- let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) ;
485+ let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) . await ;
500486 pin_mut ! ( rooms_subscriber) ;
501487 assert_pending ! ( rooms_subscriber) ;
502488
@@ -579,14 +565,14 @@ mod tests {
579565 room_list. paginate ( ) . await . unwrap ( ) ;
580566
581567 // This space contains 2 rooms
582- assert_eq ! ( room_list. rooms( ) . first( ) . unwrap( ) . room_id, child_room_id_1) ;
583- assert_eq ! ( room_list. rooms( ) . last( ) . unwrap( ) . room_id, child_room_id_2) ;
568+ assert_eq ! ( room_list. rooms( ) . await . first( ) . unwrap( ) . room_id, child_room_id_1) ;
569+ assert_eq ! ( room_list. rooms( ) . await . last( ) . unwrap( ) . room_id, child_room_id_2) ;
584570
585571 // and we don't know about either of them
586- assert_eq ! ( room_list. rooms( ) . first( ) . unwrap( ) . state, None ) ;
587- assert_eq ! ( room_list. rooms( ) . last( ) . unwrap( ) . state, None ) ;
572+ assert_eq ! ( room_list. rooms( ) . await . first( ) . unwrap( ) . state, None ) ;
573+ assert_eq ! ( room_list. rooms( ) . await . last( ) . unwrap( ) . state, None ) ;
588574
589- let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) ;
575+ let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) . await ;
590576 pin_mut ! ( rooms_subscriber) ;
591577 assert_pending ! ( rooms_subscriber) ;
592578
@@ -595,21 +581,21 @@ mod tests {
595581
596582 // Results in an update being pushed through
597583 assert_ready ! ( rooms_subscriber) ;
598- assert_eq ! ( room_list. rooms( ) . first( ) . unwrap( ) . state, Some ( RoomState :: Joined ) ) ;
599- assert_eq ! ( room_list. rooms( ) . last( ) . unwrap( ) . state, None ) ;
584+ assert_eq ! ( room_list. rooms( ) . await . first( ) . unwrap( ) . state, Some ( RoomState :: Joined ) ) ;
585+ assert_eq ! ( room_list. rooms( ) . await . last( ) . unwrap( ) . state, None ) ;
600586
601587 // Same for the second one
602588 server. sync_room ( & client, JoinedRoomBuilder :: new ( child_room_id_2) ) . await ;
603589 assert_ready ! ( rooms_subscriber) ;
604- assert_eq ! ( room_list. rooms( ) . first( ) . unwrap( ) . state, Some ( RoomState :: Joined ) ) ;
605- assert_eq ! ( room_list. rooms( ) . last( ) . unwrap( ) . state, Some ( RoomState :: Joined ) ) ;
590+ assert_eq ! ( room_list. rooms( ) . await . first( ) . unwrap( ) . state, Some ( RoomState :: Joined ) ) ;
591+ assert_eq ! ( room_list. rooms( ) . await . last( ) . unwrap( ) . state, Some ( RoomState :: Joined ) ) ;
606592
607593 // And when leaving them
608594 server. sync_room ( & client, LeftRoomBuilder :: new ( child_room_id_1) ) . await ;
609595 server. sync_room ( & client, LeftRoomBuilder :: new ( child_room_id_2) ) . await ;
610596 assert_ready ! ( rooms_subscriber) ;
611- assert_eq ! ( room_list. rooms( ) . first( ) . unwrap( ) . state, Some ( RoomState :: Left ) ) ;
612- assert_eq ! ( room_list. rooms( ) . last( ) . unwrap( ) . state, Some ( RoomState :: Left ) ) ;
597+ assert_eq ! ( room_list. rooms( ) . await . first( ) . unwrap( ) . state, Some ( RoomState :: Left ) ) ;
598+ assert_eq ! ( room_list. rooms( ) . await . last( ) . unwrap( ) . state, Some ( RoomState :: Left ) ) ;
613599 }
614600
615601 #[ async_test]
@@ -735,7 +721,7 @@ mod tests {
735721
736722 let room_list = space_service. space_room_list ( parent_space_id. to_owned ( ) ) . await ;
737723
738- let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) ;
724+ let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) . await ;
739725 pin_mut ! ( rooms_subscriber) ;
740726
741727 // When retrieving the parent and children via /hierarchy
@@ -807,7 +793,7 @@ mod tests {
807793
808794 let room_list = space_service. space_room_list ( parent_space_id. to_owned ( ) ) . await ;
809795
810- let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) ;
796+ let ( _, rooms_subscriber) = room_list. subscribe_to_room_updates ( ) . await ;
811797 pin_mut ! ( rooms_subscriber) ;
812798
813799 // Mock a /hierarchy response where one child is suggested and the other is not.
@@ -1048,21 +1034,21 @@ mod tests {
10481034 room_list. paginate ( ) . await . unwrap ( ) ;
10491035
10501036 // This space contains 1 room
1051- assert_eq ! ( room_list. rooms( ) . len( ) , 1 ) ;
1037+ assert_eq ! ( room_list. rooms( ) . await . len( ) , 1 ) ;
10521038
10531039 // Resetting the room list
10541040 room_list. reset ( ) . await ;
10551041
10561042 // Clears the rooms and pagination token
1057- assert_eq ! ( room_list. rooms( ) . len( ) , 0 ) ;
1043+ assert_eq ! ( room_list. rooms( ) . await . len( ) , 0 ) ;
10581044 assert_matches ! (
10591045 room_list. pagination_state( ) ,
10601046 SpaceRoomListPaginationState :: Idle { end_reached: false }
10611047 ) ;
10621048
10631049 // Allows paginating again
10641050 room_list. paginate ( ) . await . unwrap ( ) ;
1065- assert_eq ! ( room_list. rooms( ) . len( ) , 1 ) ;
1051+ assert_eq ! ( room_list. rooms( ) . await . len( ) , 1 ) ;
10661052 }
10671053
10681054 fn make_space_room (
0 commit comments