Skip to content

Commit c21daed

Browse files
committed
docs(redecryptor): Document the redecryptor a bit more
1 parent 8070c1e commit c21daed

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

@@ -101,6 +133,8 @@ use tokio_stream::wrappers::{
101133
};
102134
use tracing::{info, instrument, trace, warn};
103135

136+
#[cfg(doc)]
137+
use super::RoomEventCache;
104138
use crate::{
105139
Room,
106140
event_cache::{
@@ -434,7 +468,44 @@ impl EventCache {
434468

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

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

0 commit comments

Comments
 (0)