Skip to content

Commit e5487da

Browse files
committed
send queue: control enabled on a per-room basis in addition to globally
1 parent 9c1d62a commit e5487da

File tree

8 files changed

+300
-119
lines changed

8 files changed

+300
-119
lines changed

bindings/matrix-sdk-ffi/src/client.rs

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -146,14 +146,12 @@ pub trait ProgressWatcher: Send + Sync {
146146
fn transmission_progress(&self, progress: TransmissionProgress);
147147
}
148148

149-
/// A listener to the global (client-wide) status of the send queue.
149+
/// A listener to the global (client-wide) error reporter of the send queue.
150150
#[uniffi::export(callback_interface)]
151-
pub trait SendQueueStatusListener: Sync + Send {
152-
/// Called every time the send queue has received a new status.
153-
///
154-
/// This can be set automatically (in case of sending failure), or manually
155-
/// via an API call.
156-
fn on_update(&self, new_value: bool);
151+
pub trait SendQueueRoomErrorListener: Sync + Send {
152+
/// Called every time the send queue has ran into an error for a given room,
153+
/// which will disable the send queue for that particular room.
154+
fn on_error(&self, room_id: String, error: ClientError);
157155
}
158156

159157
#[derive(Clone, Copy, uniffi::Record)]
@@ -315,18 +313,15 @@ impl Client {
315313
Ok(())
316314
}
317315

318-
/// Enables or disables the send queue, according to the given parameter.
316+
/// Enables or disables all the room send queues at once.
319317
///
320-
/// The send queue automatically disables itself whenever sending an
321-
/// event with it failed (e.g., sending an event via the high-level Timeline
322-
/// object), so it's required to manually re-enable it as soon as
323-
/// connectivity is back on the device.
324-
pub fn enable_send_queue(&self, enable: bool) {
325-
if enable {
326-
self.inner.send_queue().enable();
327-
} else {
328-
self.inner.send_queue().disable();
329-
}
318+
/// When connectivity is lost on a device, it is recommended to disable the
319+
/// room sending queues.
320+
///
321+
/// This can be controlled for individual rooms, using
322+
/// [`Room::enable_send_queue`].
323+
pub fn enable_all_send_queues(&self, enable: bool) {
324+
self.inner.send_queue().set_enabled(enable);
330325
}
331326

332327
/// Subscribe to the global enablement status of the send queue, at the
@@ -336,17 +331,19 @@ impl Client {
336331
/// the enablement status.
337332
pub fn subscribe_to_send_queue_status(
338333
&self,
339-
listener: Box<dyn SendQueueStatusListener>,
334+
listener: Box<dyn SendQueueRoomErrorListener>,
340335
) -> Arc<TaskHandle> {
341-
let mut subscriber = self.inner.send_queue().subscribe_status();
336+
let mut subscriber = self.inner.send_queue().subscribe_errors();
342337

343338
Arc::new(TaskHandle::new(RUNTIME.spawn(async move {
344-
// Call with the initial value.
345-
listener.on_update(subscriber.next_now());
346-
347-
// Call every time the value changes.
348-
while let Some(next_val) = subscriber.next().await {
349-
listener.on_update(next_val);
339+
loop {
340+
match subscriber.recv().await {
341+
Ok(report) => listener
342+
.on_error(report.room_id.to_string(), ClientError::new(report.error)),
343+
Err(err) => {
344+
error!("error when listening to the send queue error reporter: {err}");
345+
}
346+
}
350347
}
351348
})))
352349
}

bindings/matrix-sdk-ffi/src/error.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ pub enum ClientError {
1414
}
1515

1616
impl ClientError {
17-
fn new<E: Display>(error: E) -> Self {
17+
pub(crate) fn new<E: Display>(error: E) -> Self {
1818
Self::Generic { msg: error.to_string() }
1919
}
2020
}

bindings/matrix-sdk-ffi/src/room.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,17 @@ impl Room {
687687
.await?;
688688
Ok(())
689689
}
690+
691+
/// Returns whether the send queue for that particular room is enabled or
692+
/// not.
693+
pub fn is_send_queue_enabled(&self) -> bool {
694+
self.inner.send_queue().is_enabled()
695+
}
696+
697+
/// Enable or disable the send queue for that particular room.
698+
pub fn enable_send_queue(&self, enable: bool) {
699+
self.inner.send_queue().set_enabled(enable);
700+
}
690701
}
691702

692703
/// Generates a `matrix.to` permalink to the given room alias.

crates/matrix-sdk-ui/tests/integration/timeline/echo.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ async fn test_retry_failed() {
142142

143143
mock_encryption_state(&server, false).await;
144144

145-
client.send_queue().enable();
145+
client.send_queue().set_enabled(true);
146146

147147
let room = client.get_room(room_id).unwrap();
148148
let timeline = Arc::new(room.timeline().await.unwrap());
@@ -173,9 +173,12 @@ async fn test_retry_failed() {
173173
.mount(&server)
174174
.await;
175175

176-
assert!(!client.send_queue().is_enabled());
176+
// This doesn't disable the send queue at the global level…
177+
assert!(client.send_queue().is_enabled());
178+
// …but does so at the local level.
179+
assert!(!room.send_queue().is_enabled());
177180

178-
client.send_queue().enable();
181+
room.send_queue().set_enabled(true);
179182

180183
// Let the send queue handle the event.
181184
tokio::time::sleep(Duration::from_millis(300)).await;

crates/matrix-sdk-ui/tests/integration/timeline/queue.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ async fn test_retry_order() {
182182
.await;
183183

184184
// Retry the second message first
185-
client.send_queue().enable();
185+
client.send_queue().set_enabled(true);
186186

187187
// Wait 200ms for the first msg, 100ms for the second, 300ms for overhead
188188
sleep(Duration::from_millis(600)).await;

0 commit comments

Comments
 (0)