38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 1 | use std::collections::HashMap; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 2 | |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 3 | use futures_util::{ |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 4 | FutureExt, |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 5 | future::{Shared, WeakShared}, |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 6 | }; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 7 | use matrix_sdk::Client; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 8 | use ruma::OwnedRoomId; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 9 | |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 10 | use super::executor::EngineBoxFuture; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 11 | use crate::Error; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 12 | |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 13 | type Flight = Shared<EngineBoxFuture<'static, Result<(), Error>>>; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 14 | |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 15 | /// one warm-up per room at a time, later asks join the one in flight |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 16 | #[derive(Default)] |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 17 | pub(super) struct Preparations( |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 18 | HashMap<OwnedRoomId, WeakShared<EngineBoxFuture<'static, Result<(), Error>>>>, |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 19 | ); |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 20 | |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 21 | impl Preparations { |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 22 | pub(super) fn join(&mut self, client: &Client, room_id: OwnedRoomId) -> Flight { |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 23 | self.0.retain(|_, flight| flight.upgrade().is_some()); |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 24 | if let Some(flight) = self.0.get(&room_id).and_then(WeakShared::upgrade) { |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 25 | return flight; |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 26 | } |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 27 | let work: EngineBoxFuture<'static, _> = Box::pin(prepare(client.clone(), room_id.clone())); |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 28 | let flight = work.shared(); |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 29 | if let Some(weak) = flight.downgrade() { |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 30 | self.0.insert(room_id, weak); |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 31 | } |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 32 | flight |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 33 | } |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 34 | } |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 35 | |
dc609022bb53 | atagen | 2026-10-08 12:39 UTC | 36 | /// the sdk's own pre-send work, run early. a send landing mid-share waits on the |
dc609022bb53 | atagen | 2026-10-08 12:39 UTC | 37 | /// sdk's per-room share lock instead of starting another (forked sdk, see design-decisions) |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 38 | async fn prepare(client: Client, room_id: OwnedRoomId) -> Result<(), Error> { |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 39 | let room = client.get_room(&room_id).ok_or_else(Error::room_unknown)?; |
dc609022bb53 | atagen | 2026-10-08 12:39 UTC | 40 | room.prepare_encryption() |
dc609022bb53 | atagen | 2026-10-08 12:39 UTC | 41 | .await |
dc609022bb53 | atagen | 2026-10-08 12:39 UTC | 42 | .map_err(|source| Error::from_sdk("preparing room encryption failed", source)) |
38c4caecdb3d | atagen | 2026-09-26 13:35 UTC | 43 | } |