@@ -164,7 +164,8 @@ use ruma::{
164
164
AnyMessageLikeEventContent , EventContent as _, Mentions ,
165
165
} ,
166
166
serde:: Raw ,
167
- MilliSecondsSinceUnixEpoch , OwnedEventId , OwnedRoomId , OwnedTransactionId , TransactionId ,
167
+ MilliSecondsSinceUnixEpoch , OwnedEventId , OwnedRoomId , OwnedTransactionId , RoomId ,
168
+ TransactionId ,
168
169
} ;
169
170
use tokio:: sync:: { broadcast, oneshot, Mutex , Notify , OwnedMutexGuard } ;
170
171
use tracing:: { debug, error, info, instrument, trace, warn} ;
@@ -242,7 +243,8 @@ impl SendQueue {
242
243
let owned_room_id = room_id. to_owned ( ) ;
243
244
let room_q = RoomSendQueue :: new (
244
245
self . is_enabled ( ) ,
245
- data. error_reporter . clone ( ) ,
246
+ data. global_update_sender . clone ( ) ,
247
+ data. error_sender . clone ( ) ,
246
248
data. is_dropping . clone ( ) ,
247
249
& self . client ,
248
250
owned_room_id. clone ( ) ,
@@ -283,10 +285,18 @@ impl SendQueue {
283
285
self . data ( ) . globally_enabled . load ( Ordering :: SeqCst )
284
286
}
285
287
288
+ /// Subscribe to all updates for all rooms.
289
+ ///
290
+ /// Use [`RoomSendQueue::subscribe`] to subscribe to update for a _specific
291
+ /// room_.
292
+ pub fn subscribe ( & self ) -> broadcast:: Receiver < SendQueueUpdate > {
293
+ self . data ( ) . global_update_sender . subscribe ( )
294
+ }
295
+
286
296
/// A subscriber to the enablement status (enabled or disabled) of the
287
297
/// send queue, along with useful errors.
288
298
pub fn subscribe_errors ( & self ) -> broadcast:: Receiver < SendQueueRoomError > {
289
- self . data ( ) . error_reporter . subscribe ( )
299
+ self . data ( ) . error_sender . subscribe ( )
290
300
}
291
301
}
292
302
@@ -325,8 +335,13 @@ pub(super) struct SendQueueData {
325
335
/// initial enablement state.
326
336
globally_enabled : AtomicBool ,
327
337
338
+ /// Global sender to send [`SendQueueUpdate`].
339
+ ///
340
+ /// See [`SendQueue::subscribe`].
341
+ global_update_sender : broadcast:: Sender < SendQueueUpdate > ,
342
+
328
343
/// Global error updates for the send queue.
329
- error_reporter : broadcast:: Sender < SendQueueRoomError > ,
344
+ error_sender : broadcast:: Sender < SendQueueRoomError > ,
330
345
331
346
/// Are we currently dropping the Client?
332
347
is_dropping : Arc < AtomicBool > ,
@@ -335,12 +350,14 @@ pub(super) struct SendQueueData {
335
350
impl SendQueueData {
336
351
/// Create the data for a send queue, in the given enabled state.
337
352
pub fn new ( globally_enabled : bool ) -> Self {
338
- let ( sender, _) = broadcast:: channel ( 32 ) ;
353
+ let ( global_update_sender, _) = broadcast:: channel ( 32 ) ;
354
+ let ( error_sender, _) = broadcast:: channel ( 32 ) ;
339
355
340
356
Self {
341
357
rooms : Default :: default ( ) ,
342
358
globally_enabled : AtomicBool :: new ( globally_enabled) ,
343
- error_reporter : sender,
359
+ global_update_sender,
360
+ error_sender,
344
361
is_dropping : Arc :: new ( false . into ( ) ) ,
345
362
}
346
363
}
@@ -385,12 +402,13 @@ impl std::fmt::Debug for RoomSendQueue {
385
402
impl RoomSendQueue {
386
403
fn new (
387
404
globally_enabled : bool ,
388
- global_error_reporter : broadcast:: Sender < SendQueueRoomError > ,
405
+ global_update_sender : broadcast:: Sender < SendQueueUpdate > ,
406
+ global_error_sender : broadcast:: Sender < SendQueueRoomError > ,
389
407
is_dropping : Arc < AtomicBool > ,
390
408
client : & Client ,
391
409
room_id : OwnedRoomId ,
392
410
) -> Self {
393
- let ( updates_sender , _) = broadcast:: channel ( 32 ) ;
411
+ let ( update_sender , _) = broadcast:: channel ( 32 ) ;
394
412
395
413
let queue = QueueStorage :: new ( WeakClient :: from_client ( client) , room_id. clone ( ) ) ;
396
414
let notifier = Arc :: new ( Notify :: new ( ) ) ;
@@ -402,16 +420,18 @@ impl RoomSendQueue {
402
420
weak_room. clone ( ) ,
403
421
queue. clone ( ) ,
404
422
notifier. clone ( ) ,
405
- updates_sender. clone ( ) ,
423
+ global_update_sender. clone ( ) ,
424
+ update_sender. clone ( ) ,
406
425
locally_enabled. clone ( ) ,
407
- global_error_reporter ,
426
+ global_error_sender ,
408
427
is_dropping,
409
428
) ) ;
410
429
411
430
Self {
412
431
inner : Arc :: new ( RoomSendQueueInner {
413
432
room : weak_room,
414
- updates : updates_sender,
433
+ global_update_sender,
434
+ update_sender,
415
435
_task : task,
416
436
queue,
417
437
notifier,
@@ -461,7 +481,7 @@ impl RoomSendQueue {
461
481
created_at,
462
482
} ;
463
483
464
- let _ = self . inner . updates . send ( RoomSendQueueUpdate :: NewLocalEvent ( LocalEcho {
484
+ self . send_update ( RoomSendQueueUpdate :: NewLocalEvent ( LocalEcho {
465
485
transaction_id,
466
486
content : LocalEchoContent :: Event {
467
487
serialized_event : content,
@@ -500,32 +520,50 @@ impl RoomSendQueue {
500
520
501
521
/// Returns the current local requests as well as a receiver to listen to
502
522
/// the send queue updates, as defined in [`RoomSendQueueUpdate`].
523
+ ///
524
+ /// Use [`SendQueue::subscribe`] to subscribe to update for _all rooms_ with
525
+ /// a single receiver.
503
526
pub async fn subscribe (
504
527
& self ,
505
528
) -> Result < ( Vec < LocalEcho > , broadcast:: Receiver < RoomSendQueueUpdate > ) , RoomSendQueueError >
506
529
{
507
530
let local_echoes = self . inner . queue . local_echoes ( self ) . await ?;
508
531
509
- Ok ( ( local_echoes, self . inner . updates . subscribe ( ) ) )
532
+ Ok ( ( local_echoes, self . inner . update_sender . subscribe ( ) ) )
510
533
}
511
534
512
535
/// A task that must be spawned in the async runtime, running in the
513
536
/// background for each room that has a send queue.
514
537
///
515
538
/// It only progresses forward: nothing can be cancelled at any point, which
516
539
/// makes the implementation not overly complicated to follow.
540
+ #[ allow( clippy:: too_many_arguments) ]
517
541
#[ instrument( skip_all, fields( room_id = %room. room_id( ) ) ) ]
518
542
async fn sending_task (
519
543
room : WeakRoom ,
520
544
queue : QueueStorage ,
521
545
notifier : Arc < Notify > ,
522
- updates : broadcast:: Sender < RoomSendQueueUpdate > ,
546
+ global_update_sender : broadcast:: Sender < SendQueueUpdate > ,
547
+ update_sender : broadcast:: Sender < RoomSendQueueUpdate > ,
523
548
locally_enabled : Arc < AtomicBool > ,
524
- global_error_reporter : broadcast:: Sender < SendQueueRoomError > ,
549
+ global_error_sender : broadcast:: Sender < SendQueueRoomError > ,
525
550
is_dropping : Arc < AtomicBool > ,
526
551
) {
527
552
trace ! ( "spawned the sending task" ) ;
528
553
554
+ fn send_update (
555
+ global_update_sender : & broadcast:: Sender < SendQueueUpdate > ,
556
+ update_sender : & broadcast:: Sender < RoomSendQueueUpdate > ,
557
+ room_id : & RoomId ,
558
+ update : RoomSendQueueUpdate ,
559
+ ) {
560
+ let _ = update_sender. send ( update. clone ( ) ) ;
561
+ let _ =
562
+ global_update_sender. send ( SendQueueUpdate { room_id : room_id. to_owned ( ) , update } ) ;
563
+ }
564
+
565
+ let room_id = room. room_id ( ) ;
566
+
529
567
loop {
530
568
// A request to shut down should be preferred above everything else.
531
569
if is_dropping. load ( Ordering :: SeqCst ) {
@@ -541,7 +579,7 @@ impl RoomSendQueue {
541
579
}
542
580
543
581
for up in new_updates {
544
- let _ = updates . send ( up) ;
582
+ send_update ( & global_update_sender , & update_sender , room_id , up) ;
545
583
}
546
584
547
585
if !locally_enabled. load ( Ordering :: SeqCst ) {
@@ -585,17 +623,24 @@ impl RoomSendQueue {
585
623
{
586
624
Ok ( ( ) ) => match parent_key {
587
625
SentRequestKey :: Event ( event_id) => {
588
- let _ = updates. send ( RoomSendQueueUpdate :: SentEvent {
589
- transaction_id : txn_id,
590
- event_id,
591
- } ) ;
626
+ send_update (
627
+ & global_update_sender,
628
+ & update_sender,
629
+ room_id,
630
+ RoomSendQueueUpdate :: SentEvent { transaction_id : txn_id, event_id } ,
631
+ ) ;
592
632
}
593
633
594
634
SentRequestKey :: Media ( media_info) => {
595
- let _ = updates. send ( RoomSendQueueUpdate :: UploadedMedia {
596
- related_to : related_txn_id. as_ref ( ) . unwrap_or ( & txn_id) . clone ( ) ,
597
- file : media_info. file ,
598
- } ) ;
635
+ send_update (
636
+ & global_update_sender,
637
+ & update_sender,
638
+ room_id,
639
+ RoomSendQueueUpdate :: UploadedMedia {
640
+ related_to : related_txn_id. as_ref ( ) . unwrap_or ( & txn_id) . clone ( ) ,
641
+ file : media_info. file ,
642
+ } ,
643
+ ) ;
599
644
}
600
645
} ,
601
646
@@ -656,17 +701,22 @@ impl RoomSendQueue {
656
701
657
702
let error = Arc :: new ( err) ;
658
703
659
- let _ = global_error_reporter . send ( SendQueueRoomError {
660
- room_id : room . room_id ( ) . to_owned ( ) ,
704
+ let _ = global_error_sender . send ( SendQueueRoomError {
705
+ room_id : room_id. to_owned ( ) ,
661
706
error : error. clone ( ) ,
662
707
is_recoverable,
663
708
} ) ;
664
709
665
- let _ = updates. send ( RoomSendQueueUpdate :: SendError {
666
- transaction_id : related_txn_id. unwrap_or ( txn_id) ,
667
- error,
668
- is_recoverable,
669
- } ) ;
710
+ send_update (
711
+ & global_update_sender,
712
+ & update_sender,
713
+ room_id,
714
+ RoomSendQueueUpdate :: SendError {
715
+ transaction_id : related_txn_id. unwrap_or ( txn_id) ,
716
+ error,
717
+ is_recoverable,
718
+ } ,
719
+ ) ;
670
720
}
671
721
}
672
722
}
@@ -804,6 +854,17 @@ impl RoomSendQueue {
804
854
self . inner . notifier . notify_one ( ) ;
805
855
}
806
856
}
857
+
858
+ /// Send an update on the room send queue channel, and on the global send
859
+ /// queue channel, i.e. it sends a [`RoomSendQueueUpdate`] and a
860
+ /// [`SendQueueUpdate`].
861
+ fn send_update ( & self , update : RoomSendQueueUpdate ) {
862
+ let _ = self . inner . update_sender . send ( update. clone ( ) ) ;
863
+ let _ = self
864
+ . inner
865
+ . global_update_sender
866
+ . send ( SendQueueUpdate { room_id : self . inner . room . room_id ( ) . to_owned ( ) , update } ) ;
867
+ }
807
868
}
808
869
809
870
impl From < & crate :: Error > for QueueWedgeError {
@@ -840,10 +901,17 @@ struct RoomSendQueueInner {
840
901
/// The room which this send queue relates to.
841
902
room : WeakRoom ,
842
903
904
+ /// Global sender to send [`SendQueueUpdate`].
905
+ ///
906
+ /// See [`SendQueue::subscribe`].
907
+ global_update_sender : broadcast:: Sender < SendQueueUpdate > ,
908
+
843
909
/// Broadcaster for notifications about the statuses of requests to be sent.
844
910
///
845
911
/// Can be subscribed to from the outside.
846
- updates : broadcast:: Sender < RoomSendQueueUpdate > ,
912
+ ///
913
+ /// See [`RoomSendQueue::subscribe`].
914
+ update_sender : broadcast:: Sender < RoomSendQueueUpdate > ,
847
915
848
916
/// Queue of requests that are either to be sent, or being sent.
849
917
///
@@ -2078,6 +2146,19 @@ pub enum RoomSendQueueUpdate {
2078
2146
} ,
2079
2147
}
2080
2148
2149
+ /// A [`RoomSendQueueUpdate`] with an associated [`OwnedRoomId`].
2150
+ ///
2151
+ /// This is used by [`SendQueue::subscribe`] to get a single channel to receive
2152
+ /// updates for all [`RoomSendQueue`]s.
2153
+ #[ derive( Clone , Debug ) ]
2154
+ pub struct SendQueueUpdate {
2155
+ /// The room where the update happened.
2156
+ pub room_id : OwnedRoomId ,
2157
+
2158
+ /// The update for this room.
2159
+ pub update : RoomSendQueueUpdate ,
2160
+ }
2161
+
2081
2162
/// An error triggered by the send queue module.
2082
2163
#[ derive( Debug , thiserror:: Error ) ]
2083
2164
pub enum RoomSendQueueError {
@@ -2200,7 +2281,7 @@ impl SendHandle {
2200
2281
for handles in & self . media_handles {
2201
2282
if queue. abort_upload ( & self . transaction_id , handles) . await ? {
2202
2283
// Propagate a cancelled update.
2203
- let _ = self . room . inner . updates . send ( RoomSendQueueUpdate :: CancelledLocalEvent {
2284
+ self . room . send_update ( RoomSendQueueUpdate :: CancelledLocalEvent {
2204
2285
transaction_id : self . transaction_id . clone ( ) ,
2205
2286
} ) ;
2206
2287
@@ -2216,7 +2297,7 @@ impl SendHandle {
2216
2297
trace ! ( "successful abort" ) ;
2217
2298
2218
2299
// Propagate a cancelled update too.
2219
- let _ = self . room . inner . updates . send ( RoomSendQueueUpdate :: CancelledLocalEvent {
2300
+ self . room . send_update ( RoomSendQueueUpdate :: CancelledLocalEvent {
2220
2301
transaction_id : self . transaction_id . clone ( ) ,
2221
2302
} ) ;
2222
2303
@@ -2249,7 +2330,7 @@ impl SendHandle {
2249
2330
self . room . inner . notifier . notify_one ( ) ;
2250
2331
2251
2332
// Propagate a replaced update too.
2252
- let _ = self . room . inner . updates . send ( RoomSendQueueUpdate :: ReplacedLocalEvent {
2333
+ self . room . send_update ( RoomSendQueueUpdate :: ReplacedLocalEvent {
2253
2334
transaction_id : self . transaction_id . clone ( ) ,
2254
2335
new_content : serializable,
2255
2336
} ) ;
@@ -2302,7 +2383,7 @@ impl SendHandle {
2302
2383
. map_err ( RoomSendQueueStorageError :: JsonSerialization ) ?;
2303
2384
2304
2385
// Propagate a replaced update too.
2305
- let _ = self . room . inner . updates . send ( RoomSendQueueUpdate :: ReplacedLocalEvent {
2386
+ self . room . send_update ( RoomSendQueueUpdate :: ReplacedLocalEvent {
2306
2387
transaction_id : self . transaction_id . clone ( ) ,
2307
2388
new_content,
2308
2389
} ) ;
@@ -2344,9 +2425,9 @@ impl SendHandle {
2344
2425
// Wake up the queue, in case the room was asleep before unwedging the request.
2345
2426
room. notifier . notify_one ( ) ;
2346
2427
2347
- let _ = room
2348
- . updates
2349
- . send ( RoomSendQueueUpdate :: RetryEvent { transaction_id : self . transaction_id . clone ( ) } ) ;
2428
+ self . room . send_update ( RoomSendQueueUpdate :: RetryEvent {
2429
+ transaction_id : self . transaction_id . clone ( ) ,
2430
+ } ) ;
2350
2431
2351
2432
Ok ( ( ) )
2352
2433
}
@@ -2377,9 +2458,9 @@ impl SendHandle {
2377
2458
transaction_id : reaction_txn_id. clone ( ) ,
2378
2459
} ;
2379
2460
2380
- let _ = self . room . inner . updates . send ( RoomSendQueueUpdate :: NewLocalEvent ( LocalEcho {
2381
- // Note: we do want to use the txn_id we're going to use for the reaction, not the
2382
- // one for the event we're reacting to.
2461
+ self . room . send_update ( RoomSendQueueUpdate :: NewLocalEvent ( LocalEcho {
2462
+ // Note: we do want to use the ` txn_id` we're going to use for the reaction, not
2463
+ // the one for the event we're reacting to.
2383
2464
transaction_id : reaction_txn_id. into ( ) ,
2384
2465
content : LocalEchoContent :: React {
2385
2466
key,
@@ -2415,7 +2496,7 @@ impl SendReactionHandle {
2415
2496
// Simple case: the reaction was found in the dependent event list.
2416
2497
2417
2498
// Propagate a cancelled update too.
2418
- let _ = self . room . inner . updates . send ( RoomSendQueueUpdate :: CancelledLocalEvent {
2499
+ self . room . send_update ( RoomSendQueueUpdate :: CancelledLocalEvent {
2419
2500
transaction_id : self . transaction_id . clone ( ) . into ( ) ,
2420
2501
} ) ;
2421
2502
0 commit comments