Hot-Reloading Refactor
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
ae1a4fd283
commit
6c1434c165
212 changed files with 5679 additions and 4206 deletions
|
@ -1,12 +1,11 @@
|
|||
pub(crate) mod data;
|
||||
pub mod data;
|
||||
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
collections::{BTreeMap, HashMap, HashSet},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
pub(crate) use data::Data;
|
||||
pub use data::Data;
|
||||
use rand::prelude::SliceRandom;
|
||||
use ruma::{
|
||||
api::{client::error::ErrorKind, federation},
|
||||
|
@ -35,60 +34,22 @@ use tracing::{debug, error, info, warn};
|
|||
|
||||
use super::state_compressor::CompressedStateEvent;
|
||||
use crate::{
|
||||
api::server_server,
|
||||
server_is_ours,
|
||||
//api::server_server,
|
||||
service::{
|
||||
self,
|
||||
appservice::NamespaceRegex,
|
||||
pdu::{EventHash, PduBuilder},
|
||||
rooms::event_handler::parse_incoming_pdu,
|
||||
},
|
||||
services,
|
||||
utils::{self, server_name::server_is_ours},
|
||||
Error, PduEvent, Result,
|
||||
utils::{self},
|
||||
Error,
|
||||
PduCount,
|
||||
PduEvent,
|
||||
Result,
|
||||
};
|
||||
|
||||
#[derive(Hash, PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub(crate) enum PduCount {
|
||||
Backfilled(u64),
|
||||
Normal(u64),
|
||||
}
|
||||
|
||||
impl PduCount {
|
||||
pub(crate) fn min() -> Self { Self::Backfilled(u64::MAX) }
|
||||
|
||||
pub(crate) fn max() -> Self { Self::Normal(u64::MAX) }
|
||||
|
||||
pub(crate) fn try_from_string(token: &str) -> Result<Self> {
|
||||
if let Some(stripped_token) = token.strip_prefix('-') {
|
||||
stripped_token.parse().map(PduCount::Backfilled)
|
||||
} else {
|
||||
token.parse().map(PduCount::Normal)
|
||||
}
|
||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Invalid pagination token."))
|
||||
}
|
||||
|
||||
pub(crate) fn stringify(&self) -> String {
|
||||
match self {
|
||||
PduCount::Backfilled(x) => format!("-{x}"),
|
||||
PduCount::Normal(x) => x.to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for PduCount {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { Some(self.cmp(other)) }
|
||||
}
|
||||
|
||||
impl Ord for PduCount {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
match (self, other) {
|
||||
(PduCount::Normal(s), PduCount::Normal(o)) => s.cmp(o),
|
||||
(PduCount::Backfilled(s), PduCount::Backfilled(o)) => o.cmp(s),
|
||||
(PduCount::Normal(_), PduCount::Backfilled(_)) => Ordering::Greater,
|
||||
(PduCount::Backfilled(_), PduCount::Normal(_)) => Ordering::Less,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update Relationships
|
||||
#[derive(Deserialize)]
|
||||
struct ExtractRelatesTo {
|
||||
|
@ -106,15 +67,15 @@ struct ExtractRelatesToEventId {
|
|||
relates_to: ExtractEventId,
|
||||
}
|
||||
|
||||
pub(crate) struct Service {
|
||||
pub(crate) db: &'static dyn Data,
|
||||
pub struct Service {
|
||||
pub db: Arc<dyn Data>,
|
||||
|
||||
pub(crate) lasttimelinecount_cache: Mutex<HashMap<OwnedRoomId, PduCount>>,
|
||||
pub lasttimelinecount_cache: Mutex<HashMap<OwnedRoomId, PduCount>>,
|
||||
}
|
||||
|
||||
impl Service {
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) fn first_pdu_in_room(&self, room_id: &RoomId) -> Result<Option<Arc<PduEvent>>> {
|
||||
pub fn first_pdu_in_room(&self, room_id: &RoomId) -> Result<Option<Arc<PduEvent>>> {
|
||||
self.all_pdus(user_id!("@doesntmatter:conduit.rs"), room_id)?
|
||||
.next()
|
||||
.map(|o| o.map(|(_, p)| Arc::new(p)))
|
||||
|
@ -122,19 +83,17 @@ impl Service {
|
|||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) fn last_timeline_count(&self, sender_user: &UserId, room_id: &RoomId) -> Result<PduCount> {
|
||||
pub fn last_timeline_count(&self, sender_user: &UserId, room_id: &RoomId) -> Result<PduCount> {
|
||||
self.db.last_timeline_count(sender_user, room_id)
|
||||
}
|
||||
|
||||
/// Returns the `count` of this pdu's id.
|
||||
pub(crate) fn get_pdu_count(&self, event_id: &EventId) -> Result<Option<PduCount>> {
|
||||
self.db.get_pdu_count(event_id)
|
||||
}
|
||||
pub fn get_pdu_count(&self, event_id: &EventId) -> Result<Option<PduCount>> { self.db.get_pdu_count(event_id) }
|
||||
|
||||
// TODO Is this the same as the function above?
|
||||
/*
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) fn latest_pdu_count(&self, room_id: &RoomId) -> Result<u64> {
|
||||
pub fn latest_pdu_count(&self, room_id: &RoomId) -> Result<u64> {
|
||||
let prefix = self
|
||||
.get_shortroomid(room_id)?
|
||||
.expect("room exists")
|
||||
|
@ -158,7 +117,7 @@ impl Service {
|
|||
///
|
||||
/// TODO: use this?
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn get_room_version(&self, room_id: &RoomId) -> Result<Option<RoomVersionId>> {
|
||||
pub fn get_room_version(&self, room_id: &RoomId) -> Result<Option<RoomVersionId>> {
|
||||
let create_event = services()
|
||||
.rooms
|
||||
.state_accessor
|
||||
|
@ -178,17 +137,17 @@ impl Service {
|
|||
}
|
||||
|
||||
/// Returns the json of a pdu.
|
||||
pub(crate) fn get_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>> {
|
||||
pub fn get_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>> {
|
||||
self.db.get_pdu_json(event_id)
|
||||
}
|
||||
|
||||
/// Returns the json of a pdu.
|
||||
pub(crate) fn get_non_outlier_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>> {
|
||||
pub fn get_non_outlier_pdu_json(&self, event_id: &EventId) -> Result<Option<CanonicalJsonObject>> {
|
||||
self.db.get_non_outlier_pdu_json(event_id)
|
||||
}
|
||||
|
||||
/// Returns the pdu's id.
|
||||
pub(crate) fn get_pdu_id(&self, event_id: &EventId) -> Result<Option<Vec<u8>>> { self.db.get_pdu_id(event_id) }
|
||||
pub fn get_pdu_id(&self, event_id: &EventId) -> Result<Option<Vec<u8>>> { self.db.get_pdu_id(event_id) }
|
||||
|
||||
/// Returns the pdu.
|
||||
///
|
||||
|
@ -196,28 +155,28 @@ impl Service {
|
|||
///
|
||||
/// TODO: use this?
|
||||
#[allow(dead_code)]
|
||||
pub(crate) fn get_non_outlier_pdu(&self, event_id: &EventId) -> Result<Option<PduEvent>> {
|
||||
pub fn get_non_outlier_pdu(&self, event_id: &EventId) -> Result<Option<PduEvent>> {
|
||||
self.db.get_non_outlier_pdu(event_id)
|
||||
}
|
||||
|
||||
/// Returns the pdu.
|
||||
///
|
||||
/// Checks the `eventid_outlierpdu` Tree if not found in the timeline.
|
||||
pub(crate) fn get_pdu(&self, event_id: &EventId) -> Result<Option<Arc<PduEvent>>> { self.db.get_pdu(event_id) }
|
||||
pub fn get_pdu(&self, event_id: &EventId) -> Result<Option<Arc<PduEvent>>> { self.db.get_pdu(event_id) }
|
||||
|
||||
/// Returns the pdu.
|
||||
///
|
||||
/// This does __NOT__ check the outliers `Tree`.
|
||||
pub(crate) fn get_pdu_from_id(&self, pdu_id: &[u8]) -> Result<Option<PduEvent>> { self.db.get_pdu_from_id(pdu_id) }
|
||||
pub fn get_pdu_from_id(&self, pdu_id: &[u8]) -> Result<Option<PduEvent>> { self.db.get_pdu_from_id(pdu_id) }
|
||||
|
||||
/// Returns the pdu as a `BTreeMap<String, CanonicalJsonValue>`.
|
||||
pub(crate) fn get_pdu_json_from_id(&self, pdu_id: &[u8]) -> Result<Option<CanonicalJsonObject>> {
|
||||
pub fn get_pdu_json_from_id(&self, pdu_id: &[u8]) -> Result<Option<CanonicalJsonObject>> {
|
||||
self.db.get_pdu_json_from_id(pdu_id)
|
||||
}
|
||||
|
||||
/// Removes a pdu and creates a new one with the same id.
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) fn replace_pdu(&self, pdu_id: &[u8], pdu_json: &CanonicalJsonObject, pdu: &PduEvent) -> Result<()> {
|
||||
pub fn replace_pdu(&self, pdu_id: &[u8], pdu_json: &CanonicalJsonObject, pdu: &PduEvent) -> Result<()> {
|
||||
self.db.replace_pdu(pdu_id, pdu_json, pdu)
|
||||
}
|
||||
|
||||
|
@ -228,7 +187,7 @@ impl Service {
|
|||
///
|
||||
/// Returns pdu id
|
||||
#[tracing::instrument(skip(self, pdu, pdu_json, leaves))]
|
||||
pub(crate) async fn append_pdu(
|
||||
pub async fn append_pdu(
|
||||
&self,
|
||||
pdu: &PduEvent,
|
||||
mut pdu_json: CanonicalJsonObject,
|
||||
|
@ -513,7 +472,6 @@ impl Service {
|
|||
// This will evaluate to false if the emergency password is set up so that
|
||||
// the administrator can execute commands as conduit
|
||||
let from_conduit = pdu.sender == server_user && services().globals.emergency_password().is_none();
|
||||
|
||||
if let Some(admin_room) = service::admin::Service::get_admin_room().await? {
|
||||
if to_conduit && !from_conduit && admin_room == pdu.room_id {
|
||||
services()
|
||||
|
@ -628,7 +586,7 @@ impl Service {
|
|||
Ok(pdu_id)
|
||||
}
|
||||
|
||||
pub(crate) fn create_hash_and_sign_event(
|
||||
pub fn create_hash_and_sign_event(
|
||||
&self,
|
||||
pdu_builder: PduBuilder,
|
||||
sender: &UserId,
|
||||
|
@ -811,7 +769,7 @@ impl Service {
|
|||
/// takes a roomid_mutex_state, meaning that only this function is able to
|
||||
/// mutate the room state.
|
||||
#[tracing::instrument(skip(self, state_lock))]
|
||||
pub(crate) async fn build_and_append_pdu(
|
||||
pub async fn build_and_append_pdu(
|
||||
&self,
|
||||
pdu_builder: PduBuilder,
|
||||
sender: &UserId,
|
||||
|
@ -819,7 +777,6 @@ impl Service {
|
|||
state_lock: &MutexGuard<'_, ()>, // Take mutex guard to make sure users get the room state mutex
|
||||
) -> Result<Arc<EventId>> {
|
||||
let (pdu, pdu_json) = self.create_hash_and_sign_event(pdu_builder, sender, room_id, state_lock)?;
|
||||
|
||||
if let Some(admin_room) = service::admin::Service::get_admin_room().await? {
|
||||
if admin_room == room_id {
|
||||
match pdu.event_type() {
|
||||
|
@ -951,7 +908,7 @@ impl Service {
|
|||
/// Append the incoming event setting the state snapshot to the state from
|
||||
/// the server that sent the event.
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn append_incoming_pdu(
|
||||
pub async fn append_incoming_pdu(
|
||||
&self,
|
||||
pdu: &PduEvent,
|
||||
pdu_json: CanonicalJsonObject,
|
||||
|
@ -990,7 +947,7 @@ impl Service {
|
|||
}
|
||||
|
||||
/// Returns an iterator over all PDUs in a room.
|
||||
pub(crate) fn all_pdus<'a>(
|
||||
pub fn all_pdus<'a>(
|
||||
&'a self, user_id: &UserId, room_id: &RoomId,
|
||||
) -> Result<impl Iterator<Item = Result<(PduCount, PduEvent)>> + 'a> {
|
||||
self.pdus_after(user_id, room_id, PduCount::min())
|
||||
|
@ -1000,7 +957,7 @@ impl Service {
|
|||
/// happened before the event with id `until` in reverse-chronological
|
||||
/// order.
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) fn pdus_until<'a>(
|
||||
pub fn pdus_until<'a>(
|
||||
&'a self, user_id: &UserId, room_id: &RoomId, until: PduCount,
|
||||
) -> Result<impl Iterator<Item = Result<(PduCount, PduEvent)>> + 'a> {
|
||||
self.db.pdus_until(user_id, room_id, until)
|
||||
|
@ -1009,7 +966,7 @@ impl Service {
|
|||
/// Returns an iterator over all events and their token in a room that
|
||||
/// happened after the event with id `from` in chronological order.
|
||||
#[tracing::instrument(skip(self))]
|
||||
pub(crate) fn pdus_after<'a>(
|
||||
pub fn pdus_after<'a>(
|
||||
&'a self, user_id: &UserId, room_id: &RoomId, from: PduCount,
|
||||
) -> Result<impl Iterator<Item = Result<(PduCount, PduEvent)>> + 'a> {
|
||||
self.db.pdus_after(user_id, room_id, from)
|
||||
|
@ -1017,7 +974,7 @@ impl Service {
|
|||
|
||||
/// Replace a PDU with the redacted form.
|
||||
#[tracing::instrument(skip(self, reason))]
|
||||
pub(crate) fn redact_pdu(&self, event_id: &EventId, reason: &PduEvent) -> Result<()> {
|
||||
pub fn redact_pdu(&self, event_id: &EventId, reason: &PduEvent) -> Result<()> {
|
||||
// TODO: Don't reserialize, keep original json
|
||||
if let Some(pdu_id) = self.get_pdu_id(event_id)? {
|
||||
let mut pdu = self
|
||||
|
@ -1039,7 +996,7 @@ impl Service {
|
|||
}
|
||||
|
||||
#[tracing::instrument(skip(self, room_id))]
|
||||
pub(crate) async fn backfill_if_required(&self, room_id: &RoomId, from: PduCount) -> Result<()> {
|
||||
pub async fn backfill_if_required(&self, room_id: &RoomId, from: PduCount) -> Result<()> {
|
||||
let first_pdu = self
|
||||
.all_pdus(user_id!("@doesntmatter:conduit.rs"), room_id)?
|
||||
.next()
|
||||
|
@ -1154,11 +1111,11 @@ impl Service {
|
|||
}
|
||||
|
||||
#[tracing::instrument(skip(self, pdu, pub_key_map))]
|
||||
pub(crate) async fn backfill_pdu(
|
||||
pub async fn backfill_pdu(
|
||||
&self, origin: &ServerName, pdu: Box<RawJsonValue>,
|
||||
pub_key_map: &RwLock<BTreeMap<String, BTreeMap<String, Base64>>>,
|
||||
) -> Result<()> {
|
||||
let (event_id, value, room_id) = server_server::parse_incoming_pdu(&pdu)?;
|
||||
let (event_id, value, room_id) = parse_incoming_pdu(&pdu)?;
|
||||
|
||||
// Lock so we cannot backfill the same pdu twice at the same time
|
||||
let mutex = Arc::clone(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue