Skip to main content

tuwunel_service/migrations/
fix_bad_double_separator_in_state_cache.rs

1use tuwunel_core::{
2	Result, debug_info, debug_warn, info,
3	itertools::Itertools,
4	utils::{ReadyExt, stream::TryIgnore},
5	warn,
6};
7
8use crate::Services;
9
10pub(super) async fn fix_bad_double_separator_in_state_cache(services: &Services) -> Result {
11	warn!("Fixing bad double separator in state_cache roomuserid_joined");
12
13	let db = &services.db;
14	let roomuserid_joined = &db["roomuserid_joined"];
15	let _cork = db.cork_and_sync();
16
17	let mut iter_count: usize = 0;
18
19	roomuserid_joined
20		.raw_stream()
21		.ignore_err()
22		.ready_for_each(|(key, value)| {
23			let mut key = key.to_vec();
24			iter_count = iter_count.saturating_add(1);
25			debug_info!(%iter_count);
26			let Some(first_sep_index) = key.iter().position(|&i| i == 0xFF) else {
27				debug_warn!(?key, "roomuserid_joined key has no 0xFF separator; skipping");
28				return;
29			};
30
31			if key
32				.iter()
33				.get(first_sep_index..=first_sep_index.saturating_add(1))
34				.copied()
35				.collect_vec()
36				== vec![0xFF, 0xFF]
37			{
38				debug_warn!("Found bad key: {key:?}");
39				roomuserid_joined.remove(&key);
40
41				key.remove(first_sep_index);
42				debug_warn!("Fixed key: {key:?}");
43				roomuserid_joined.insert(&key, value);
44			}
45		})
46		.await;
47
48	info!("Finished fixing");
49
50	db["global"].insert(b"fix_bad_double_separator_in_state_cache", []);
51	roomuserid_joined.sort()
52}