fix: long prev event fetch times for huge rooms
This commit is contained in:
parent
665aee11c0
commit
9410d3ef9c
3 changed files with 49 additions and 38 deletions
|
@ -272,7 +272,7 @@ impl Database {
|
||||||
referencedevents: builder.open_tree("referencedevents")?,
|
referencedevents: builder.open_tree("referencedevents")?,
|
||||||
pdu_cache: Mutex::new(LruCache::new(100_000)),
|
pdu_cache: Mutex::new(LruCache::new(100_000)),
|
||||||
auth_chain_cache: Mutex::new(LruCache::new(100_000)),
|
auth_chain_cache: Mutex::new(LruCache::new(100_000)),
|
||||||
shorteventid_cache: Mutex::new(LruCache::new(100_000)),
|
shorteventid_cache: Mutex::new(LruCache::new(1_000_000)),
|
||||||
},
|
},
|
||||||
account_data: account_data::AccountData {
|
account_data: account_data::AccountData {
|
||||||
roomuserdataid_accountdata: builder.open_tree("roomuserdataid_accountdata")?,
|
roomuserdataid_accountdata: builder.open_tree("roomuserdataid_accountdata")?,
|
||||||
|
|
|
@ -99,15 +99,11 @@ impl Rooms {
|
||||||
Ok(self
|
Ok(self
|
||||||
.stateid_shorteventid
|
.stateid_shorteventid
|
||||||
.scan_prefix(shortstatehash.to_be_bytes().to_vec())
|
.scan_prefix(shortstatehash.to_be_bytes().to_vec())
|
||||||
.map(|(_, bytes)| self.shorteventid_eventid.get(&bytes).ok().flatten())
|
.map(|(_, bytes)| {
|
||||||
.flatten()
|
self.get_eventid_from_short(utils::u64_from_bytes(&bytes).unwrap())
|
||||||
.map(|bytes| {
|
.ok()
|
||||||
EventId::try_from(utils::string_from_bytes(&bytes).map_err(|_| {
|
|
||||||
Error::bad_database("EventID in stateid_shorteventid is invalid unicode.")
|
|
||||||
})?)
|
|
||||||
.map_err(|_| Error::bad_database("EventId in stateid_shorteventid is invalid."))
|
|
||||||
})
|
})
|
||||||
.filter_map(|r| r.ok())
|
.flatten()
|
||||||
.collect())
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,15 +114,11 @@ impl Rooms {
|
||||||
let state = self
|
let state = self
|
||||||
.stateid_shorteventid
|
.stateid_shorteventid
|
||||||
.scan_prefix(shortstatehash.to_be_bytes().to_vec())
|
.scan_prefix(shortstatehash.to_be_bytes().to_vec())
|
||||||
.map(|(_, bytes)| self.shorteventid_eventid.get(&bytes).ok().flatten())
|
.map(|(_, bytes)| {
|
||||||
.flatten()
|
self.get_eventid_from_short(utils::u64_from_bytes(&bytes).unwrap())
|
||||||
.map(|bytes| {
|
.ok()
|
||||||
EventId::try_from(utils::string_from_bytes(&bytes).map_err(|_| {
|
|
||||||
Error::bad_database("EventID in stateid_shorteventid is invalid unicode.")
|
|
||||||
})?)
|
|
||||||
.map_err(|_| Error::bad_database("EventId in stateid_shorteventid is invalid."))
|
|
||||||
})
|
})
|
||||||
.filter_map(|r| r.ok())
|
.flatten()
|
||||||
.map(|eventid| self.get_pdu(&eventid))
|
.map(|eventid| self.get_pdu(&eventid))
|
||||||
.filter_map(|r| r.ok().flatten())
|
.filter_map(|r| r.ok().flatten())
|
||||||
.map(|pdu| {
|
.map(|pdu| {
|
||||||
|
@ -168,15 +160,10 @@ impl Rooms {
|
||||||
Ok(self
|
Ok(self
|
||||||
.stateid_shorteventid
|
.stateid_shorteventid
|
||||||
.get(&stateid)?
|
.get(&stateid)?
|
||||||
.map(|bytes| self.shorteventid_eventid.get(&bytes).ok().flatten())
|
|
||||||
.flatten()
|
|
||||||
.map(|bytes| {
|
.map(|bytes| {
|
||||||
EventId::try_from(utils::string_from_bytes(&bytes).map_err(|_| {
|
self.get_eventid_from_short(utils::u64_from_bytes(&bytes).unwrap())
|
||||||
Error::bad_database("EventID in stateid_shorteventid is invalid unicode.")
|
.ok()
|
||||||
})?)
|
|
||||||
.map_err(|_| Error::bad_database("EventId in stateid_shorteventid is invalid."))
|
|
||||||
})
|
})
|
||||||
.map(|r| r.ok())
|
|
||||||
.flatten())
|
.flatten())
|
||||||
} else {
|
} else {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
|
@ -448,7 +435,12 @@ impl Rooms {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_eventid_from_short(&self, shorteventid: u64) -> Result<EventId> {
|
pub fn get_eventid_from_short(&self, shorteventid: u64) -> Result<EventId> {
|
||||||
if let Some(id) = self.shorteventid_cache.lock().unwrap().get_mut(&shorteventid) {
|
if let Some(id) = self
|
||||||
|
.shorteventid_cache
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.get_mut(&shorteventid)
|
||||||
|
{
|
||||||
return Ok(id.clone());
|
return Ok(id.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,11 +449,10 @@ impl Rooms {
|
||||||
.get(&shorteventid.to_be_bytes())?
|
.get(&shorteventid.to_be_bytes())?
|
||||||
.ok_or_else(|| Error::bad_database("Shorteventid does not exist"))?;
|
.ok_or_else(|| Error::bad_database("Shorteventid does not exist"))?;
|
||||||
|
|
||||||
let event_id = EventId::try_from(
|
let event_id =
|
||||||
utils::string_from_bytes(&bytes).map_err(|_| {
|
EventId::try_from(utils::string_from_bytes(&bytes).map_err(|_| {
|
||||||
Error::bad_database("EventID in roomid_pduleaves is invalid unicode.")
|
Error::bad_database("EventID in roomid_pduleaves is invalid unicode.")
|
||||||
})?,
|
})?)
|
||||||
)
|
|
||||||
.map_err(|_| Error::bad_database("EventId in roomid_pduleaves is invalid."))?;
|
.map_err(|_| Error::bad_database("EventId in roomid_pduleaves is invalid."))?;
|
||||||
|
|
||||||
self.shorteventid_cache
|
self.shorteventid_cache
|
||||||
|
|
|
@ -668,7 +668,7 @@ pub async fn send_transaction_message_route(
|
||||||
|
|
||||||
let elapsed = start_time.elapsed();
|
let elapsed = start_time.elapsed();
|
||||||
warn!(
|
warn!(
|
||||||
"Handling event {} took {}m{}s",
|
"Handling transaction of event {} took {}m{}s",
|
||||||
event_id,
|
event_id,
|
||||||
elapsed.as_secs() / 60,
|
elapsed.as_secs() / 60,
|
||||||
elapsed.as_secs() % 60
|
elapsed.as_secs() % 60
|
||||||
|
@ -850,6 +850,8 @@ pub fn handle_incoming_pdu<'a>(
|
||||||
pub_key_map: &'a RwLock<BTreeMap<String, BTreeMap<String, String>>>,
|
pub_key_map: &'a RwLock<BTreeMap<String, BTreeMap<String, String>>>,
|
||||||
) -> AsyncRecursiveType<'a, StdResult<Option<Vec<u8>>, String>> {
|
) -> AsyncRecursiveType<'a, StdResult<Option<Vec<u8>>, String>> {
|
||||||
Box::pin(async move {
|
Box::pin(async move {
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
// TODO: For RoomVersion6 we must check that Raw<..> is canonical do we anywhere?: https://matrix.org/docs/spec/rooms/v6#canonical-json
|
// TODO: For RoomVersion6 we must check that Raw<..> is canonical do we anywhere?: https://matrix.org/docs/spec/rooms/v6#canonical-json
|
||||||
match db.rooms.exists(&room_id) {
|
match db.rooms.exists(&room_id) {
|
||||||
Ok(true) => {}
|
Ok(true) => {}
|
||||||
|
@ -1014,12 +1016,18 @@ pub fn handle_incoming_pdu<'a>(
|
||||||
// 8. if not timeline event: stop
|
// 8. if not timeline event: stop
|
||||||
if !is_timeline_event
|
if !is_timeline_event
|
||||||
|| incoming_pdu.origin_server_ts
|
|| incoming_pdu.origin_server_ts
|
||||||
< db.rooms
|
< (utils::millis_since_unix_epoch() - 1000 * 60 * 20)
|
||||||
.first_pdu_in_room(&room_id)
|
.try_into()
|
||||||
.map_err(|_| "Error loading first room event.".to_owned())?
|
.expect("time is valid")
|
||||||
.expect("Room exists")
|
// Not older than 20 mins
|
||||||
.origin_server_ts
|
|
||||||
{
|
{
|
||||||
|
let elapsed = start_time.elapsed();
|
||||||
|
warn!(
|
||||||
|
"Handling outlier event {} took {}m{}s",
|
||||||
|
event_id,
|
||||||
|
elapsed.as_secs() / 60,
|
||||||
|
elapsed.as_secs() % 60
|
||||||
|
);
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1312,7 +1320,8 @@ pub fn handle_incoming_pdu<'a>(
|
||||||
for state in fork_states {
|
for state in fork_states {
|
||||||
auth_chain_sets.push(
|
auth_chain_sets.push(
|
||||||
get_auth_chain(state.iter().map(|(_, id)| id.clone()).collect(), db)
|
get_auth_chain(state.iter().map(|(_, id)| id.clone()).collect(), db)
|
||||||
.map_err(|_| "Failed to load auth chain.".to_owned())?.collect(),
|
.map_err(|_| "Failed to load auth chain.".to_owned())?
|
||||||
|
.collect(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1385,6 +1394,14 @@ pub fn handle_incoming_pdu<'a>(
|
||||||
|
|
||||||
// Event has passed all auth/stateres checks
|
// Event has passed all auth/stateres checks
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
|
||||||
|
let elapsed = start_time.elapsed();
|
||||||
|
warn!(
|
||||||
|
"Handling timeline event {} took {}m{}s",
|
||||||
|
event_id,
|
||||||
|
elapsed.as_secs() / 60,
|
||||||
|
elapsed.as_secs() % 60
|
||||||
|
);
|
||||||
Ok(pdu_id)
|
Ok(pdu_id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1757,7 +1774,10 @@ fn append_incoming_pdu(
|
||||||
Ok(pdu_id)
|
Ok(pdu_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_auth_chain(starting_events: Vec<EventId>, db: &Database) -> Result<impl Iterator<Item = EventId> + '_> {
|
fn get_auth_chain(
|
||||||
|
starting_events: Vec<EventId>,
|
||||||
|
db: &Database,
|
||||||
|
) -> Result<impl Iterator<Item = EventId> + '_> {
|
||||||
let mut full_auth_chain = HashSet::new();
|
let mut full_auth_chain = HashSet::new();
|
||||||
|
|
||||||
let starting_events = starting_events
|
let starting_events = starting_events
|
||||||
|
|
Loading…
Reference in a new issue