feat: improved state store

This commit is contained in:
Timo Kösters 2020-12-19 16:00:11 +01:00
parent 6e5b35ea92
commit 6606e41dde
No known key found for this signature in database
GPG key ID: 24DA7517711A2BA4
13 changed files with 405 additions and 251 deletions

View file

@ -1,5 +1,5 @@
use super::State;
use crate::{appservice_server, server_server, ConduitResult, Database, Error, Ruma};
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::{
api::{
appservice,
@ -66,12 +66,14 @@ pub async fn get_alias_helper(
room_alias: &RoomAliasId,
) -> ConduitResult<get_alias::Response> {
if room_alias.server_name() != db.globals.server_name() {
let response = server_server::send_request(
&db.globals,
room_alias.server_name().to_owned(),
federation::query::get_room_information::v1::Request { room_alias },
)
.await?;
let response = db
.sending
.send_federation_request(
&db.globals,
room_alias.server_name().to_owned(),
federation::query::get_room_information::v1::Request { room_alias },
)
.await?;
return Ok(get_alias::Response::new(response.room_id, response.servers).into());
}
@ -81,13 +83,15 @@ pub async fn get_alias_helper(
Some(r) => room_id = Some(r),
None => {
for (_id, registration) in db.appservice.iter_all().filter_map(|r| r.ok()) {
if appservice_server::send_request(
&db.globals,
registration,
appservice::query::query_room_alias::v1::Request { room_alias },
)
.await
.is_ok()
if db
.sending
.send_appservice_request(
&db.globals,
registration,
appservice::query::query_room_alias::v1::Request { room_alias },
)
.await
.is_ok()
{
room_id = Some(db.rooms.id_from_alias(&room_alias)?.ok_or_else(|| {
Error::bad_config("Appservice lied to us. Room does not exist.")

View file

@ -1,5 +1,5 @@
use super::State;
use crate::{server_server, ConduitResult, Database, Error, Result, Ruma};
use crate::{ConduitResult, Database, Error, Result, Ruma};
use log::info;
use ruma::{
api::{
@ -133,19 +133,21 @@ pub async fn get_public_rooms_filtered_helper(
.clone()
.filter(|server| *server != db.globals.server_name().as_str())
{
let response = server_server::send_request(
&db.globals,
other_server.to_owned(),
federation::directory::get_public_rooms_filtered::v1::Request {
limit,
since: since.as_deref(),
filter: Filter {
generic_search_term: filter.generic_search_term.as_deref(),
let response = db
.sending
.send_federation_request(
&db.globals,
other_server.to_owned(),
federation::directory::get_public_rooms_filtered::v1::Request {
limit,
since: since.as_deref(),
filter: Filter {
generic_search_term: filter.generic_search_term.as_deref(),
},
room_network: RoomNetwork::Matrix,
},
room_network: RoomNetwork::Matrix,
},
)
.await?;
)
.await?;
return Ok(get_public_rooms_filtered::Response {
chunk: response

View file

@ -1,7 +1,5 @@
use super::State;
use crate::{
database::media::FileMeta, server_server, utils, ConduitResult, Database, Error, Ruma,
};
use crate::{database::media::FileMeta, utils, ConduitResult, Database, Error, Ruma};
use ruma::api::client::{
error::ErrorKind,
r0::media::{create_content, get_content, get_content_thumbnail, get_media_config},
@ -45,7 +43,11 @@ pub async fn create_content_route(
db.flush().await?;
Ok(create_content::Response { content_uri: mxc, blurhash: None }.into())
Ok(create_content::Response {
content_uri: mxc,
blurhash: None,
}
.into())
}
#[cfg_attr(
@ -71,16 +73,18 @@ pub async fn get_content_route(
}
.into())
} else if &*body.server_name != db.globals.server_name() && body.allow_remote {
let get_content_response = server_server::send_request(
&db.globals,
body.server_name.clone(),
get_content::Request {
allow_remote: false,
server_name: &body.server_name,
media_id: &body.media_id,
},
)
.await?;
let get_content_response = db
.sending
.send_federation_request(
&db.globals,
body.server_name.clone(),
get_content::Request {
allow_remote: false,
server_name: &body.server_name,
media_id: &body.media_id,
},
)
.await?;
db.media.create(
mxc,
@ -118,19 +122,21 @@ pub async fn get_content_thumbnail_route(
)? {
Ok(get_content_thumbnail::Response { file, content_type }.into())
} else if &*body.server_name != db.globals.server_name() && body.allow_remote {
let get_thumbnail_response = server_server::send_request(
&db.globals,
body.server_name.clone(),
get_content_thumbnail::Request {
allow_remote: false,
height: body.height,
width: body.width,
method: body.method,
server_name: &body.server_name,
media_id: &body.media_id,
},
)
.await?;
let get_thumbnail_response = db
.sending
.send_federation_request(
&db.globals,
body.server_name.clone(),
get_content_thumbnail::Request {
allow_remote: false,
height: body.height,
width: body.width,
method: body.method,
server_name: &body.server_name,
media_id: &body.media_id,
},
)
.await?;
db.media.upload_thumbnail(
mxc,

View file

@ -2,7 +2,7 @@ use super::State;
use crate::{
client_server,
pdu::{PduBuilder, PduEvent},
server_server, utils, ConduitResult, Database, Error, Result, Ruma,
utils, ConduitResult, Database, Error, Result, Ruma,
};
use log::warn;
use ruma::{
@ -401,9 +401,10 @@ pub async fn get_member_events_route(
Ok(get_member_events::Response {
chunk: db
.rooms
.room_state_type(&body.room_id, &EventType::RoomMember)?
.values()
.map(|pdu| pdu.to_member_event())
.room_state_full(&body.room_id)?
.iter()
.filter(|(key, _)| key.0 == EventType::RoomMember)
.map(|(_, pdu)| pdu.to_member_event())
.collect(),
}
.into())
@ -463,16 +464,18 @@ async fn join_room_by_id_helper(
));
for remote_server in servers {
let make_join_response = server_server::send_request(
&db.globals,
remote_server.clone(),
federation::membership::create_join_event_template::v1::Request {
room_id,
user_id: sender_user,
ver: &[RoomVersionId::Version5, RoomVersionId::Version6],
},
)
.await;
let make_join_response = db
.sending
.send_federation_request(
&db.globals,
remote_server.clone(),
federation::membership::create_join_event_template::v1::Request {
room_id,
user_id: sender_user,
ver: &[RoomVersionId::Version5, RoomVersionId::Version6],
},
)
.await;
make_join_response_and_server = make_join_response.map(|r| (r, remote_server));
@ -540,16 +543,18 @@ async fn join_room_by_id_helper(
// It has enough fields to be called a proper event now
let join_event = join_event_stub;
let send_join_response = server_server::send_request(
&db.globals,
remote_server.clone(),
federation::membership::create_join_event::v2::Request {
room_id,
event_id: &event_id,
pdu: PduEvent::convert_to_outgoing_federation_event(join_event.clone()),
},
)
.await?;
let send_join_response = db
.sending
.send_federation_request(
&db.globals,
remote_server.clone(),
federation::membership::create_join_event::v2::Request {
room_id,
event_id: &event_id,
pdu: PduEvent::convert_to_outgoing_federation_event(join_event.clone()),
},
)
.await?;
let add_event_id = |pdu: &Raw<Pdu>| -> Result<(EventId, CanonicalJsonObject)> {
let mut value = serde_json::from_str(pdu.json().get())
@ -694,7 +699,7 @@ async fn join_room_by_id_helper(
}
}
db.rooms.force_state(room_id, state)?;
db.rooms.force_state(room_id, state, &db.globals)?;
} else {
let event = member::MemberEventContent {
membership: member::MembershipState::Join,

View file

@ -1,7 +1,9 @@
use super::State;
use crate::{ConduitResult, Database, Error, Ruma};
use ruma::{
api::client::{error::ErrorKind, r0::read_marker::set_read_marker},
api::client::{
error::ErrorKind, r0::capabilities::get_capabilities, r0::read_marker::set_read_marker,
},
events::{AnyEphemeralRoomEvent, AnyEvent, EventType},
};
@ -76,3 +78,18 @@ pub async fn set_read_marker_route(
Ok(set_read_marker::Response.into())
}
#[cfg_attr(
feature = "conduit_bin",
post("/_matrix/client/r0/rooms/<_>/receipt/<_>/<_>", data = "<body>")
)]
pub async fn set_receipt_route(
db: State<'_, Database>,
body: Ruma<get_capabilities::Request>,
) -> ConduitResult<set_read_marker::Response> {
let _sender_user = body.sender_user.as_ref().expect("user is authenticated");
db.flush().await?;
Ok(set_read_marker::Response.into())
}

View file

@ -102,9 +102,15 @@ pub async fn sync_events_route(
}
// Database queries:
let encrypted_room = db
.rooms
.room_state_get(&room_id, &EventType::RoomEncryption, "")?
let current_state = db.rooms.room_state_full(&room_id)?;
let current_members = current_state
.iter()
.filter(|(key, _)| key.0 == EventType::RoomMember)
.map(|(key, value)| (&key.1, value)) // Only keep state key
.collect::<Vec<_>>();
let encrypted_room = current_state
.get(&(EventType::RoomEncryption, "".to_owned()))
.is_some();
// These type is Option<Option<_>>. The outer Option is None when there is no event between
@ -117,45 +123,45 @@ pub async fn sync_events_route(
.as_ref()
.map(|pdu| db.rooms.pdu_state_hash(&pdu.as_ref().ok()?.0).ok()?);
let since_members = since_state_hash.as_ref().map(|state_hash| {
state_hash.as_ref().and_then(|state_hash| {
db.rooms
.state_type(&state_hash, &EventType::RoomMember)
.ok()
})
let since_state = since_state_hash.as_ref().map(|state_hash| {
state_hash
.as_ref()
.and_then(|state_hash| db.rooms.state_full(&room_id, &state_hash).ok())
});
let since_encryption = since_state_hash.as_ref().map(|state_hash| {
state_hash.as_ref().and_then(|state_hash| {
db.rooms
.state_get(&state_hash, &EventType::RoomEncryption, "")
.ok()
})
let since_encryption = since_state.as_ref().map(|state| {
state
.as_ref()
.map(|state| state.get(&(EventType::RoomEncryption, "".to_owned())))
});
let current_members = db.rooms.room_state_type(&room_id, &EventType::RoomMember)?;
// Calculations:
let new_encrypted_room =
encrypted_room && since_encryption.map_or(false, |encryption| encryption.is_none());
let send_member_count = since_members.as_ref().map_or(false, |since_members| {
since_members.as_ref().map_or(true, |since_members| {
current_members.len() != since_members.len()
let send_member_count = since_state.as_ref().map_or(false, |since_state| {
since_state.as_ref().map_or(true, |since_state| {
current_members.len()
!= since_state
.iter()
.filter(|(key, _)| key.0 == EventType::RoomMember)
.count()
})
});
let since_sender_member = since_members.as_ref().map(|since_members| {
since_members.as_ref().and_then(|members| {
members.get(sender_user.as_str()).and_then(|pdu| {
serde_json::from_value::<Raw<ruma::events::room::member::MemberEventContent>>(
pdu.content.clone(),
)
.expect("Raw::from_value always works")
.deserialize()
.map_err(|_| Error::bad_database("Invalid PDU in database."))
.ok()
})
let since_sender_member = since_state.as_ref().map(|since_state| {
since_state.as_ref().and_then(|state| {
state
.get(&(EventType::RoomMember, sender_user.as_str().to_owned()))
.and_then(|pdu| {
serde_json::from_value::<
Raw<ruma::events::room::member::MemberEventContent>,
>(pdu.content.clone())
.expect("Raw::from_value always works")
.deserialize()
.map_err(|_| Error::bad_database("Invalid PDU in database."))
.ok()
})
})
});
@ -170,30 +176,32 @@ pub async fn sync_events_route(
.membership;
let since_membership =
since_members
since_state
.as_ref()
.map_or(MembershipState::Join, |members| {
members
.map_or(MembershipState::Join, |since_state| {
since_state
.as_ref()
.and_then(|members| {
members.get(&user_id).and_then(|since_member| {
serde_json::from_value::<
Raw<ruma::events::room::member::MemberEventContent>,
>(
since_member.content.clone()
)
.expect("Raw::from_value always works")
.deserialize()
.map_err(|_| {
Error::bad_database("Invalid PDU in database.")
.and_then(|since_state| {
since_state
.get(&(EventType::RoomMember, user_id.clone()))
.and_then(|since_member| {
serde_json::from_value::<
Raw<ruma::events::room::member::MemberEventContent>,
>(
since_member.content.clone()
)
.expect("Raw::from_value always works")
.deserialize()
.map_err(|_| {
Error::bad_database("Invalid PDU in database.")
})
.ok()
})
.ok()
})
})
.map_or(MembershipState::Leave, |member| member.membership)
});
let user_id = UserId::try_from(user_id)
let user_id = UserId::try_from(user_id.clone())
.map_err(|_| Error::bad_database("Invalid UserId in member PDU."))?;
match (since_membership, current_membership) {
@ -456,7 +464,12 @@ pub async fn sync_events_route(
})
.and_then(|state_hash| {
db.rooms
.state_get(&state_hash, &EventType::RoomMember, sender_user.as_str())
.state_get(
&room_id,
&state_hash,
&EventType::RoomMember,
sender_user.as_str(),
)
.ok()?
.ok_or_else(|| Error::bad_database("State hash in db doesn't have a state."))
.ok()