Fix sync handling for appservices calling without device_id

This commit is contained in:
dasha_uwu
2025-12-14 11:25:58 +05:00
committed by Jason Volk
parent 7b2079f714
commit 0c7ba1dd5a
15 changed files with 118 additions and 74 deletions

View File

@@ -59,7 +59,7 @@ pub struct Room {
type Connections = TokioMutex<BTreeMap<ConnectionKey, ConnectionVal>>;
pub type ConnectionVal = Arc<TokioMutex<Connection>>;
pub type ConnectionKey = (OwnedUserId, OwnedDeviceId, Option<ConnectionId>);
pub type ConnectionKey = (OwnedUserId, Option<OwnedDeviceId>, Option<ConnectionId>);
pub type Subscriptions = BTreeMap<OwnedRoomId, request::ListConfig>;
pub type Lists = BTreeMap<ListId, request::List>;
@@ -107,7 +107,7 @@ pub async fn clear_connections(
.await
.retain(|(conn_user_id, conn_device_id, conn_conn_id), _| {
let retain = user_id.is_none_or(is_equal_to!(conn_user_id))
&& device_id.is_none_or(is_equal_to!(conn_device_id))
&& (device_id.is_none() || device_id == conn_device_id.as_deref())
&& (conn_id.is_none() || conn_id == conn_conn_id.as_ref());
if !retain {
@@ -215,13 +215,17 @@ pub async fn is_connection_stored(&self, key: &ConnectionKey) -> bool {
}
#[inline]
pub fn into_connection_key<U, D, C>(user_id: U, device_id: D, conn_id: Option<C>) -> ConnectionKey
pub fn into_connection_key<U, D, C>(
user_id: U,
device_id: Option<D>,
conn_id: Option<C>,
) -> ConnectionKey
where
U: Into<OwnedUserId>,
D: Into<OwnedDeviceId>,
C: Into<ConnectionId>,
{
(user_id.into(), device_id.into(), conn_id.map(Into::into))
(user_id.into(), device_id.map(Into::into), conn_id.map(Into::into))
}
#[implement(Connection)]

View File

@@ -8,25 +8,18 @@ use tuwunel_database::{Interfix, Separator, serialize_key};
pub async fn watch<'a, Rooms>(
&self,
user_id: &UserId,
device_id: &DeviceId,
device_id: Option<&DeviceId>,
rooms: Rooms,
) -> Result
where
Rooms: Stream<Item = &'a RoomId> + Send + 'a,
{
let userdeviceid_prefix = (user_id, device_id, Interfix);
let globaluserdata_prefix = (Separator, user_id, Interfix);
let roomuserdataid_prefix = (Option::<&RoomId>::None, user_id, Interfix);
let userid_prefix =
serialize_key((user_id, Interfix)).expect("failed to serialize watch prefix");
let watchers = [
// Return when *any* user changed their key
// TODO: only send for user they share a room with
self.db
.todeviceid_events
.watch_prefix(&userdeviceid_prefix)
.boxed(),
self.db
.userroomid_joined
.watch_raw_prefix(&userid_prefix)
@@ -72,8 +65,20 @@ where
.boxed(),
];
let mut futures = FuturesUnordered::new();
futures.extend(watchers.into_iter());
let device_watchers = device_id.into_iter().map(|device_id| {
// Return when *any* user changed their key
// TODO: only send for user they share a room with
let userdeviceid_prefix = (user_id, device_id, Interfix);
self.db
.todeviceid_events
.watch_prefix(&userdeviceid_prefix)
.boxed()
});
let mut futures: FuturesUnordered<_> = watchers
.into_iter()
.chain(device_watchers)
.collect();
pin_mut!(rooms);
while let Some(room_id) = rooms.next().await {