Skip to content

Commit 96422b3

Browse files
committed
send queue: wake up the sending task after editing an event
It could be that the last event in a room's send queue has been marked as wedged. In that case, the task will sleep until it's notified again. If the event is being edited, then nothing would wake up the task; a manual wakeup might be required in that case. The new integration test shows the issue; the last `assert_update` would fail with a timeout before this patch.
1 parent eac2076 commit 96422b3

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

crates/matrix-sdk/src/send_queue.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,9 @@ impl SendHandle {
899899
if self.room.inner.queue.replace(&self.transaction_id, serializable.clone()).await? {
900900
trace!("successful edit");
901901

902+
// Wake up the queue, in case the room was asleep before the edit.
903+
self.room.inner.notifier.notify_one();
904+
902905
// Propagate a replaced update too.
903906
let _ = self.room.inner.updates.send(RoomSendQueueUpdate::ReplacedLocalEvent {
904907
transaction_id: self.transaction_id.clone(),

crates/matrix-sdk/tests/integration/send_queue.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,73 @@ async fn test_edit() {
885885
assert!(watch.is_empty());
886886
}
887887

888+
#[async_test]
889+
async fn test_edit_wakes_the_sending_task() {
890+
let (client, server) = logged_in_client_with_server().await;
891+
892+
// Mark the room as joined.
893+
let room_id = room_id!("!a:b.c");
894+
895+
let room = mock_sync_with_new_room(
896+
|builder| {
897+
builder.add_joined_room(JoinedRoomBuilder::new(room_id));
898+
},
899+
&client,
900+
&server,
901+
room_id,
902+
)
903+
.await;
904+
905+
let q = room.send_queue();
906+
907+
let (local_echoes, mut watch) = q.subscribe().await.unwrap();
908+
909+
assert!(local_echoes.is_empty());
910+
assert!(watch.is_empty());
911+
912+
mock_encryption_state(&server, false).await;
913+
914+
let send_mock_scope = Mock::given(method("PUT"))
915+
.and(path_regex(r"^/_matrix/client/r0/rooms/.*/send/.*"))
916+
.and(header("authorization", "Bearer 1234"))
917+
.respond_with(ResponseTemplate::new(413).set_body_json(json!({
918+
// From https://spec.matrix.org/v1.10/client-server-api/#standard-error-response
919+
"errcode": "M_TOO_LARGE",
920+
})))
921+
.expect(1)
922+
.mount_as_scoped(&server)
923+
.await;
924+
925+
let handle =
926+
q.send(RoomMessageEventContent::text_plain("welcome to my ted talk").into()).await.unwrap();
927+
928+
// Receiving an update for the local echo.
929+
let (txn, _) = assert_update!(watch => local echo { body = "welcome to my ted talk" });
930+
assert!(watch.is_empty());
931+
932+
// Let the background task start now.
933+
tokio::task::yield_now().await;
934+
935+
assert_update!(watch => error { recoverable = false, txn = txn });
936+
assert!(watch.is_empty());
937+
938+
// Now edit the event's content (imagine we make it "shorter").
939+
drop(send_mock_scope);
940+
mock_send_event(event_id!("$1")).mount(&server).await;
941+
942+
let edited = handle
943+
.edit(RoomMessageEventContent::text_plain("here's the summary of my ted talk").into())
944+
.await
945+
.unwrap();
946+
assert!(edited);
947+
948+
// Let the server process the message.
949+
assert_update!(watch => edit { body = "here's the summary of my ted talk", txn = txn });
950+
assert_update!(watch => sent { txn = txn, });
951+
952+
assert!(watch.is_empty());
953+
}
954+
888955
#[async_test]
889956
async fn test_abort_after_disable() {
890957
let (client, server) = logged_in_client_with_server().await;

0 commit comments

Comments
 (0)