Skip to content

Commit 66d6f49

Browse files
committed
feat(timeline): Listen to the room keys stream to retry decryptions
1 parent ad77d20 commit 66d6f49

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

crates/matrix-sdk-ui/src/timeline/builder.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ use matrix_sdk::{
2323
};
2424
use ruma::{events::AnySyncTimelineEvent, RoomVersionId};
2525
use tokio::sync::broadcast::error::RecvError;
26+
use tokio_stream::wrappers::errors::BroadcastStreamRecvError;
2627
use tracing::{info, info_span, trace, warn, Instrument, Span};
2728

2829
use super::{
@@ -426,6 +427,44 @@ impl TimelineBuilder {
426427
})
427428
};
428429

430+
// TODO: Technically this should™ be the only stream we need to listen to get
431+
// notified when we should retry to decrypt an event. We sadly can't do that,
432+
// since the cross-process support kills the `OlmMachine` which then in
433+
// turn kills this stream. Once this is solved remove all the other ways we
434+
// listen for room keys.
435+
let room_keys_received_join_handle = {
436+
let inner = controller.clone();
437+
let stream = client.encryption().room_keys_received_stream().await.expect("");
438+
439+
spawn(async move {
440+
pin_mut!(stream);
441+
442+
while let Some(room_keys) = stream.next().await {
443+
let session_ids = match room_keys {
444+
Ok(room_keys) => {
445+
let session_ids: BTreeSet<String> = room_keys
446+
.into_iter()
447+
.filter(|info| info.room_id == inner.room().room_id())
448+
.map(|info| info.session_id)
449+
.collect();
450+
451+
Some(session_ids)
452+
}
453+
Err(BroadcastStreamRecvError::Lagged(missed_updates)) => {
454+
// We lagged, let's retry to decrypt anything we have, maybe something
455+
// was received.
456+
warn!(missed_updates, "The room keys stream has lagged, retrying to decrypt the whole timeline");
457+
458+
None
459+
}
460+
};
461+
462+
let room = inner.room();
463+
inner.retry_event_decryption(room, session_ids).await;
464+
}
465+
})
466+
};
467+
429468
let timeline = Timeline {
430469
controller,
431470
event_cache: room_event_cache,
@@ -436,6 +475,7 @@ impl TimelineBuilder {
436475
pinned_events_join_handle,
437476
room_key_from_backups_join_handle,
438477
room_key_backup_enabled_join_handle,
478+
room_keys_received_join_handle,
439479
local_echo_listener_handle,
440480
_event_cache_drop_handle: event_cache_drop,
441481
encryption_changes_handle,

crates/matrix-sdk-ui/src/timeline/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,7 @@ struct TimelineDropHandle {
816816
room_update_join_handle: JoinHandle<()>,
817817
pinned_events_join_handle: Option<JoinHandle<()>>,
818818
room_key_from_backups_join_handle: JoinHandle<()>,
819+
room_keys_received_join_handle: JoinHandle<()>,
819820
room_key_backup_enabled_join_handle: JoinHandle<()>,
820821
local_echo_listener_handle: JoinHandle<()>,
821822
_event_cache_drop_handle: Arc<EventCacheDropHandles>,
@@ -836,6 +837,7 @@ impl Drop for TimelineDropHandle {
836837
self.room_update_join_handle.abort();
837838
self.room_key_from_backups_join_handle.abort();
838839
self.room_key_backup_enabled_join_handle.abort();
840+
self.room_keys_received_join_handle.abort();
839841
self.encryption_changes_handle.abort();
840842
}
841843
}

0 commit comments

Comments
 (0)