mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-15 13:16:56 +00:00
perf: Strip unsigned over federation and generate it on the fly locally
This commit is contained in:
14 files changed
+263
-79
No files matched your search
@@ -100,7 +100,7 @@ fn set_unsigned_adds_the_sticky_ttl() {
|
||||
// section
|
||||
let mut pdu = sticky_pdu(&serde_json::json!({ "duration_ms": 300_000 }));
|
||||
pdu.origin_server_ts = ruma::MilliSecondsSinceUnixEpoch::now().get();
|
||||
pdu.set_unsigned(None);
|
||||
pdu.set_unsigned(None, None, None, None);
|
||||
|
||||
let unsigned: serde_json::Value =
|
||||
serde_json::from_str(pdu.unsigned.as_deref().expect("unsigned is set").get())
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
use std::{borrow::Borrow, collections::BTreeMap};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use ruma::MilliSecondsSinceUnixEpoch;
|
||||
use ruma::{
|
||||
MilliSecondsSinceUnixEpoch,
|
||||
events::{AnyTimelineEvent, room::member::MembershipState},
|
||||
serde::Raw,
|
||||
};
|
||||
use serde_json::value::{RawValue as RawJsonValue, Value as JsonValue, to_raw_value};
|
||||
|
||||
use super::{Pdu, sticky};
|
||||
use crate::{Result, err, result::LogErr};
|
||||
use crate::{Event, Result, err, result::LogErr};
|
||||
|
||||
type Unsigned = BTreeMap<String, Box<RawJsonValue>>;
|
||||
|
||||
impl Pdu {
|
||||
/// Set the `unsigned` field of the PDU using only information in the PDU.
|
||||
@@ -12,51 +18,52 @@ impl Pdu {
|
||||
/// threads). Once this is done, other data must be calculated from the
|
||||
/// database (eg. relations) This is for server-to-client events.
|
||||
/// Backfill handles this itself.
|
||||
pub fn set_unsigned(&mut self, user_id: Option<&ruma::UserId>) {
|
||||
if Some(self.sender.borrow()) != user_id {
|
||||
self.remove_transaction_id().log_err().ok();
|
||||
}
|
||||
self.add_age().log_err().ok();
|
||||
self.add_sticky_duration_ttl().log_err().ok();
|
||||
}
|
||||
|
||||
pub fn remove_transaction_id(&mut self) -> Result {
|
||||
use BTreeMap as Map;
|
||||
|
||||
let Some(unsigned) = &self.unsigned else {
|
||||
return Ok(());
|
||||
pub fn set_unsigned(
|
||||
&mut self,
|
||||
user_id: Option<&ruma::UserId>,
|
||||
membership: Option<MembershipState>,
|
||||
prev_content: Option<Box<RawJsonValue>>,
|
||||
redacted_because: Option<Raw<AnyTimelineEvent>>,
|
||||
) {
|
||||
// See: https://spec.matrix.org/v1.19/client-server-api/#definition-clientevent_unsigneddata
|
||||
let Some(mut unsigned) = self
|
||||
.unsigned()
|
||||
.and_then(|u| serde_json::from_str::<Unsigned>(u.get()).ok())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut unsigned: Map<&str, Box<RawJsonValue>> = serde_json::from_str(unsigned.get())
|
||||
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
|
||||
let now: ruma::Int = MilliSecondsSinceUnixEpoch::now().get().into();
|
||||
unsigned.insert(
|
||||
"age".to_owned(),
|
||||
to_raw_value(&now.saturating_sub(self.origin_server_ts.into())).unwrap(),
|
||||
);
|
||||
|
||||
unsigned.remove("transaction_id");
|
||||
self.unsigned = to_raw_value(&unsigned)
|
||||
.map(Some)
|
||||
.expect("unsigned is valid");
|
||||
if let Some(membership) = membership {
|
||||
unsigned.insert("membership".to_owned(), to_raw_value(&membership).unwrap());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
if let Some(prev_content) = prev_content {
|
||||
unsigned.insert(
|
||||
"prev_content".to_owned(),
|
||||
to_raw_value(&prev_content)
|
||||
.expect("prev_content must be a valid JSON value for unsigned"),
|
||||
);
|
||||
}
|
||||
if let Some(redacted_because) = redacted_because {
|
||||
unsigned.remove("redacted_because_id");
|
||||
unsigned.insert(
|
||||
"redacted_because".to_owned(),
|
||||
to_raw_value(&redacted_because)
|
||||
.expect("redacted_because must be a valid JSON value for unsigned"),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn add_age(&mut self) -> Result {
|
||||
use BTreeMap as Map;
|
||||
|
||||
let mut unsigned: Map<&str, Box<RawJsonValue>> = self
|
||||
.unsigned
|
||||
.as_deref()
|
||||
.map(RawJsonValue::get)
|
||||
.map_or_else(|| Ok(Map::new()), serde_json::from_str)
|
||||
.map_err(|e| err!(Database("Invalid unsigned in pdu event: {e}")))?;
|
||||
|
||||
// deliberately allowing for the possibility of negative age
|
||||
let now: i128 = MilliSecondsSinceUnixEpoch::now().get().into();
|
||||
let then: i128 = self.origin_server_ts.into();
|
||||
let this_age = now.saturating_sub(then);
|
||||
|
||||
unsigned.insert("age", to_raw_value(&this_age)?);
|
||||
self.unsigned = Some(to_raw_value(&unsigned)?);
|
||||
|
||||
Ok(())
|
||||
// Remove transaction_id unless the user is the sender
|
||||
if user_id.is_none_or(|u| u != self.sender()) {
|
||||
unsigned.remove("transaction_id");
|
||||
}
|
||||
self.add_sticky_duration_ttl().log_err().ok();
|
||||
}
|
||||
|
||||
pub fn add_sticky_duration_ttl(&mut self) -> Result {
|
||||
|
||||
Reference in new issue
Block a user