Skip to content

Commit 0f4bbe5

Browse files
committed
docs(redecryptor): Document the redecryptor a bit more
1 parent 82573a3 commit 0f4bbe5

File tree

1 file changed

+135
-25
lines changed

1 file changed

+135
-25
lines changed

crates/matrix-sdk/src/event_cache/redecryptor.rs

Lines changed: 135 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,26 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
//! The Redecryptor (Rd) is a layer and long-running background task which
16-
//! handles redecryption of events in case we couldn't decrypt them imediatelly.
15+
//! The Redecryptor (affectionately known as R2D2) is a layer and long-running
16+
//! background task which handles redecryption of events in case we couldn't
17+
//! decrypt them imediatelly.
1718
//!
18-
//! Rd listens to the OlmMachine for received room keys and new
19+
//! There are various reasons why a room key might not be available imediatelly
20+
//! when the event becomes available:
21+
//! - The to-device message containing the room key just arrives late, i.e.
22+
//! after the room event.
23+
//! - The event is a historic event and we need to first download the room
24+
//! key from the backup.
25+
//! - The event is a historic event in a previously unjoined room, we need
26+
//! to receive historic room keys as defined in [MSC3061](https://github.com/matrix-org/matrix-spec/pull/1655#issuecomment-2213152255).
27+
//!
28+
//! R2D2 listens to the OlmMachine for received room keys and new
1929
//! m.room_key.withheld events.
2030
//!
2131
//! If a new room key has been received it attempts to find any UTDs in the
22-
//! [`EventCache`]. If Rd decrypts any UTDs from the event cache it will replace
23-
//! the events in the cache and send out new [`RoomEventCacheUpdates`] to any of
24-
//! its listeners.
32+
//! [`EventCache`]. If R2D2 decrypts any UTDs from the event cache it will
33+
//! replace the events in the cache and send out new [`RoomEventCacheUpdates`]
34+
//! to any of its listeners.
2535
//!
2636
//! If a new withheld info has been received it attempts to find any relevant
2737
//! events and updates the [`EncryptionInfo`] of an event.
@@ -31,28 +41,49 @@
3141
//! a `None` on the room keys stream and we need to re-listen to it.
3242
//!
3343
//! Another gotcha is that room keys might be received on another process if the
34-
//! Client is operating on a iOS device. A separate process is used in this case
35-
//! to receive push notifications. In this case the room key will be received
36-
//! and Rd won't get notified about it. To work around this decryption requests
37-
//! can be explicitly sent to Rd.
44+
//! Client is operating on a Apple device. A separate process is used in this
45+
//! case to receive push notifications. In this case the room key will be
46+
//! received and R2D2 won't get notified about it. To work around this
47+
//! decryption requests can be explicitly sent to R2D2.
3848
//!
49+
//! ```markdown
50+
//!
51+
//! .----------------------.
52+
//! | |
53+
//! | Beeb, boop! |
54+
//! | .
55+
//! ----------------------._ \
56+
//! -; _____
57+
//! .`/L|__`.
58+
//! / =[_]O|` \
59+
//! |"+_____":|
60+
//! __:='|____`-:__
61+
//! ||[] ||====|| []||
62+
//! ||[] ||====|| []||
63+
//! |:== ||====|| ==:|
64+
//! ||[] ||====|| []||
65+
//! ||[] ||====|| []||
66+
//! _||_ ||====|| _||_
67+
//! (====) |:====:| (====)
68+
//! }--{ | | | | }--{
69+
//! (____) |_| |_| (____)
3970
//!
4071
//! ┌─────────────┐
4172
//! │ │
42-
//! ┌───────────┤ Timeline │◄────────────┐
73+
//! ┌───────────┤ Timeline │◄────────────┐
4374
//! │ │ │ │
44-
//! │ └─────▲───────┘ │
45-
//! │
46-
//! │
47-
//! │
48-
//! Decryption Redecryptor
49-
//! request report
50-
//! │ RoomEventCacheUpdates
51-
//! │
52-
//! │
53-
//! │ ┌──────────┴────────────┐ │
75+
//! │ └──────▲──────┘ │
76+
//! │
77+
//! │
78+
//! │
79+
//! Decryption Redecryptor
80+
//! request report
81+
//! │ RoomEventCacheUpdates
82+
//! │
83+
//! │
84+
//! │ ┌───────────┴───────────┐ │
5485
//! │ │ │ │
55-
//! └──────► Redecryptor │────────┘
86+
//! └──────► R2D2 │────────┘
5687
//! │ │
5788
//! └───────────▲───────────┘
5889
//! │
@@ -67,6 +98,7 @@
6798
//! │ OlmMachine │
6899
//! │ │
69100
//! └──────────────┘
101+
//! ```
70102
71103
use std::{collections::BTreeSet, pin::Pin, sync::Weak};
72104

@@ -104,6 +136,8 @@ use tokio_stream::wrappers::{
104136
};
105137
use tracing::{info, instrument, trace, warn};
106138

139+
#[cfg(doc)]
140+
use super::RoomEventCache;
107141
use crate::{
108142
Room,
109143
event_cache::{
@@ -437,7 +471,44 @@ impl EventCache {
437471

438472
/// Explicitly request the redecryption of a set of events.
439473
///
440-
/// TODO: Explain when and why this might be useful.
474+
/// The redecryption logic in the event cache might sometimes miss that a
475+
/// room key has become available and that a certain set of events has
476+
/// become decryptable.
477+
///
478+
/// This might happen because some room keys might arrive in a separate
479+
/// process handling push notifications or if a room key arrives but the
480+
/// process shuts down before we could have decrypted the events.
481+
///
482+
/// For this reason it is useful to tell the event cache explicitly that
483+
/// some events should be retried to be redecrypted.
484+
///
485+
/// This method allows you to do so. The events that get decrypted, if any,
486+
/// will be advertised over the usual event cache subscription mechanism
487+
/// which can be accessed using the [`RoomEventCache::subscribe()`]
488+
/// method.
489+
///
490+
/// # Examples
491+
///
492+
/// ```no_run
493+
/// # use matrix_sdk::{Client, event_cache::DecryptionRetryRequest};
494+
/// # use url::Url;
495+
/// # use ruma::owned_room_id;
496+
/// # use std::collections::BTreeSet;
497+
/// # async {
498+
/// # let homeserver = Url::parse("http://localhost:8080")?;
499+
/// # let client = Client::new(homeserver).await?;
500+
/// let event_cache = client.event_cache();
501+
/// let room_id = owned_room_id!("!my_room:localhost");
502+
///
503+
/// let request = DecryptionRetryRequest {
504+
/// room_id,
505+
/// utd_session_ids: BTreeSet::from(["session_id".into()]),
506+
/// refresh_info_session_ids: BTreeSet::new(),
507+
/// };
508+
///
509+
/// event_cache.request_decryption(request);
510+
/// # anyhow::Ok(()) };
511+
/// ```
441512
pub fn request_decryption(&self, request: DecryptionRetryRequest) {
442513
let _ =
443514
self.inner.redecryption_channels.decryption_request_sender.send(request).inspect_err(
@@ -447,8 +518,47 @@ impl EventCache {
447518

448519
/// Subscribe to reports that the redecryptor generates.
449520
///
450-
/// TODO: Explain when the redecryptor might send such reports.
451-
pub fn subscrube_to_decryption_reports(
521+
/// The redecryption logic in the event cache might sometimes miss that a
522+
/// room key has become available and that a certain set of events has
523+
/// become decryptable.
524+
///
525+
/// This might happen because some room keys might arrive in a separate
526+
/// process handling push notifications or if room keys arrive faster than
527+
/// we can handle them.
528+
///
529+
/// This stream can be used to get notified about such situations as well as
530+
/// a general channel where the event cache reports which events got
531+
/// successfully redecrypted.
532+
///
533+
/// # Examples
534+
///
535+
/// ```no_run
536+
/// # use matrix_sdk::{Client, event_cache::RedecryptorReport};
537+
/// # use url::Url;
538+
/// # use tokio_stream::StreamExt;
539+
/// # async {
540+
/// # let homeserver = Url::parse("http://localhost:8080")?;
541+
/// # let client = Client::new(homeserver).await?;
542+
/// let event_cache = client.event_cache();
543+
///
544+
/// let mut stream = event_cache.subscribe_to_decryption_reports();
545+
///
546+
/// while let Some(Ok(report)) = stream.next().await {
547+
/// match report {
548+
/// RedecryptorReport::Lagging => {
549+
/// // The event cache might have missed to redecrypt some events. We should tell
550+
/// // it which events we care about, i.e. which events we're displaying to the
551+
/// // user, and let it redecrypt things with an explicit request.
552+
/// }
553+
/// RedecryptorReport::ResolvedUtds { .. } => {
554+
/// // This may be interesting for statistical reasons or in case we'd like to
555+
/// // fetch and inspect these events in some manner.
556+
/// }
557+
/// }
558+
/// }
559+
/// # anyhow::Ok(()) };
560+
/// ```
561+
pub fn subscribe_to_decryption_reports(
452562
&self,
453563
) -> impl Stream<Item = Result<RedecryptorReport, BroadcastStreamRecvError>> {
454564
BroadcastStream::new(self.inner.redecryption_channels.utd_reporter.subscribe())

0 commit comments

Comments
 (0)