atagen

macltok

public
Star0
Watch0

Commit 123824465d8b

tarball

atagen <boss@atagen.co>2026-10-26 09:21 UTC

3 files changed+41-28
room: time out a timeline build that never returns

On the first launch after an upgrade, a device build's room opens sat in build_timeline forever and held each room's open with them. After 60s the room now answers with a Timeline error and its actor exits, so the next open retries from scratch. Takes the fork's build-step logging (2eb08d9c).
Modified file: Cargo.lock+10 additions−10 deletions
@@ -2217,7 +2217,7 @@ dependencies = [
22172217 [[package]]
22182218 name = "matrix-sdk"
22192219 version = "0.18.0"
2220-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2220+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
22212221 dependencies = [
22222222 "anymap2",
22232223 "aquamarine",
@@ -2280,7 +2280,7 @@ dependencies = [
22802280 [[package]]
22812281 name = "matrix-sdk-base"
22822282 version = "0.18.0"
2283-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2283+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
22842284 dependencies = [
22852285 "as_variant",
22862286 "assert_matches",
@@ -2310,7 +2310,7 @@ dependencies = [
23102310 [[package]]
23112311 name = "matrix-sdk-common"
23122312 version = "0.18.0"
2313-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2313+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
23142314 dependencies = [
23152315 "eyeball-im",
23162316 "futures-core",
@@ -2333,7 +2333,7 @@ dependencies = [
23332333 [[package]]
23342334 name = "matrix-sdk-crypto"
23352335 version = "0.18.0"
2336-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2336+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
23372337 dependencies = [
23382338 "aes",
23392339 "aquamarine",
@@ -2374,7 +2374,7 @@ dependencies = [
23742374 [[package]]
23752375 name = "matrix-sdk-indexeddb"
23762376 version = "0.18.0"
2377-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2377+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
23782378 dependencies = [
23792379 "async-trait",
23802380 "base64",
@@ -2406,7 +2406,7 @@ dependencies = [
24062406 [[package]]
24072407 name = "matrix-sdk-sqlite"
24082408 version = "0.18.0"
2409-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2409+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
24102410 dependencies = [
24112411 "as_variant",
24122412 "async-trait",
@@ -2433,7 +2433,7 @@ dependencies = [
24332433 [[package]]
24342434 name = "matrix-sdk-store-encryption"
24352435 version = "0.18.0"
2436-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2436+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
24372437 dependencies = [
24382438 "base64",
24392439 "blake3",
@@ -2454,7 +2454,7 @@ dependencies = [
24542454 [[package]]
24552455 name = "matrix-sdk-test"
24562456 version = "0.18.0"
2457-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2457+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
24582458 dependencies = [
24592459 "as_variant",
24602460 "ctor",
@@ -2477,7 +2477,7 @@ dependencies = [
24772477 [[package]]
24782478 name = "matrix-sdk-test-macros"
24792479 version = "0.18.0"
2480-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2480+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
24812481 dependencies = [
24822482 "quote",
24832483 "syn 2.0.119",
@@ -2486,7 +2486,7 @@ dependencies = [
24862486 [[package]]
24872487 name = "matrix-sdk-ui"
24882488 version = "0.18.0"
2489-source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=a88b3d82b396fdba1a14adb0e01dc6a5d284bccb#a88b3d82b396fdba1a14adb0e01dc6a5d284bccb"
2489+source = "git+ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk?rev=2eb08d9cad5296d2fc398ca929aef94d6bca843d#2eb08d9cad5296d2fc398ca929aef94d6bca843d"
24902490 dependencies = [
24912491 "as_variant",
24922492 "async-rx",
Modified file: Cargo.toml+9 additions−9 deletions
@@ -26,11 +26,11 @@ indexeddb = [
2626 futures-util = { version = "0.3.31", default-features = false, features = ["std"] }
2727 http = "1"
2828 imbl = { version = "6.1.0", default-features = false }
29-matrix-sdk = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", default-features = false, features = ["e2e-encryption"] }
30-matrix-sdk-base = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", default-features = false }
31-matrix-sdk-crypto = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", default-features = false }
32-matrix-sdk-store-encryption = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", optional = true }
33-matrix-sdk-ui = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", default-features = false }
29+matrix-sdk = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", default-features = false, features = ["e2e-encryption"] }
30+matrix-sdk-base = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", default-features = false }
31+matrix-sdk-crypto = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", default-features = false }
32+matrix-sdk-store-encryption = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", optional = true }
33+matrix-sdk-ui = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", default-features = false }
3434 ruma = { version = "0.16.0", default-features = false, features = ["unstable-msc2545", "unstable-msc4095"] }
3535 serde = { version = "1.0.219", features = ["derive", "rc"], optional = true }
3636 serde_json = { version = "1.0.143", features = ["raw_value"] }
@@ -54,8 +54,8 @@ js-sys = { version = "0.3.105", optional = true }
5454 # tantivy 0.26's merger reads Instant::now() whenever debug logging is on, and that panics in
5555 # wasm. both caps, since a release_max_level a host sets would otherwise win in release
5656 log = { version = "0.4.29", features = ["max_level_info", "release_max_level_info"] }
57-matrix-sdk = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", default-features = false, features = ["js"] }
58-matrix-sdk-ui = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", default-features = false, features = ["js"] }
57+matrix-sdk = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", default-features = false, features = ["js"] }
58+matrix-sdk-ui = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", default-features = false, features = ["js"] }
5959 # the sdk's own wasm reqwest leaves out stream, which the bounded media download needs
6060 reqwest = { version = "0.13.1", default-features = false, features = ["stream"] }
6161 uuid = { version = "1", features = ["js"] }
@@ -73,8 +73,8 @@ web-sys = { version = "0.3.105", optional = true, features = [
7373 tokio = { version = "1.47.1", features = ["rt"] }
7474
7575 [target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
76-matrix-sdk = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb", default-features = false, features = ["testing"] }
77-matrix-sdk-test = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "a88b3d82b396fdba1a14adb0e01dc6a5d284bccb" }
76+matrix-sdk = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d", default-features = false, features = ["testing"] }
77+matrix-sdk-test = { git = "ssh://brewery@pls.lobotomise.me:33/atagen/matrix-rust-sdk", rev = "2eb08d9cad5296d2fc398ca929aef94d6bca843d" }
7878 tokio = { version = "1.47.1", features = ["macros", "rt-multi-thread", "signal", "time"] }
7979 wiremock = "0.6.5"
8080
Modified file: src/engine/room.rs+22 additions−9 deletions
@@ -13,6 +13,10 @@ use crate::{
1313 TypingState, transport::Responder,
1414 };
1515
16+/// a build stuck on the event cache would otherwise hold the room's open forever. a big room on
17+/// a slow device can take tens of seconds to load from IndexedDB, so this is generous
18+const BUILD_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(60);
19+
1620 pub(super) enum ActorRequest {
1721 /// opening an open room answers with a fresh reset
1822 Open(Responder),
@@ -74,16 +78,27 @@ impl RoomActor {
7478
7579 async fn serve(&mut self) {
7680 tracing::debug!(room_id = %self.room_id, "building the room timeline");
77- let timeline = match build_timeline(
81+ let build = build_timeline(
7882 &self.room,
7983 TimelineFocus::Live {
8084 hide_threaded_events: true,
8185 },
82- )
83- .await
84- {
85- Ok(timeline) => timeline,
86- Err(error) => return self.refuse_everything(error).await,
86+ );
87+ let timeout = matrix_sdk::sleep::sleep(BUILD_TIMEOUT);
88+ let timeline = tokio::select! {
89+ built = build => match built {
90+ Ok(timeline) => timeline,
91+ Err(error) => {
92+ tracing::warn!(%error, room_id = %self.room_id, "room actor could not build its timeline");
93+ let error = Error::with_source(ErrorKind::Timeline, "room timeline build failed", error);
94+ return self.refuse_everything(error).await;
95+ }
96+ },
97+ () = timeout => {
98+ tracing::warn!(room_id = %self.room_id, "room timeline build timed out");
99+ let error = Error::new(ErrorKind::Timeline, "room timeline build timed out");
100+ return self.refuse_everything(error).await;
101+ }
87102 };
88103 tracing::debug!(room_id = %self.room_id, "starting the room timeline session");
89104 let Ok(room_timeline) = TimelineSession::start(
@@ -251,9 +266,7 @@ impl RoomActor {
251266 }
252267 }
253268
254- async fn refuse_everything(&mut self, error: matrix_sdk_ui::timeline::Error) {
255- tracing::warn!(%error, room_id = %self.room_id, "room actor could not build its timeline");
256- let error = Error::with_source(ErrorKind::Timeline, "room timeline build failed", error);
269+ async fn refuse_everything(&mut self, error: Error) {
257270 for reply in self.opening.drain(..) {
258271 reply.done(Err(error.clone()));
259272 }