mirror of
https://forgejo.ellis.link/continuwuation/continuwuity/
synced 2026-10-06 08:27:17 +00:00
revert d330930bb5
revert feat: Add timestamp to event endpoint This implementation unfortunately resulted in resource exhaustion when run on some rooms.
This commit is contained in:
@@ -1 +0,0 @@
|
||||
Added the `GET /_matrix/client/v1/rooms/{roomId}/timestamp_to_event` endpoint as per MSC3030, letting clients find the event closest to a given timestamp. Contributed by @eleboucher.
|
||||
@@ -3,11 +3,10 @@
|
||||
mod event;
|
||||
mod initial_sync;
|
||||
mod summary;
|
||||
mod timestamp_to_event;
|
||||
mod upgrade;
|
||||
|
||||
pub(crate) use self::{
|
||||
aliases::get_room_aliases_route, create::create_room_route, event::get_room_event_route,
|
||||
initial_sync::room_initial_sync_route, summary::get_room_summary,
|
||||
timestamp_to_event::get_event_by_timestamp_route, upgrade::upgrade_room_route,
|
||||
upgrade::upgrade_room_route,
|
||||
};
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
use axum::extract::State;
|
||||
use conduwuit::{Err, Event, Result, err};
|
||||
use ruma::api::{Direction, client::room::get_event_by_timestamp};
|
||||
|
||||
use crate::Ruma;
|
||||
|
||||
/// # `GET /_matrix/client/v1/rooms/{roomId}/timestamp_to_event`
|
||||
///
|
||||
/// Gets the ID of the event closest to the given timestamp, in the direction
|
||||
/// specified by `dir`.
|
||||
pub(crate) async fn get_event_by_timestamp_route(
|
||||
State(ref services): State<crate::State>,
|
||||
body: Ruma<get_event_by_timestamp::v1::Request>,
|
||||
) -> Result<get_event_by_timestamp::v1::Response> {
|
||||
let sender_user = body.identity.expect_sender_user()?;
|
||||
let room_id = &body.room_id;
|
||||
|
||||
if !services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.user_can_see_state_events(sender_user, room_id)
|
||||
.await
|
||||
{
|
||||
return Err!(Request(Forbidden("You don't have permission to view this room.")));
|
||||
}
|
||||
|
||||
let dir = match body.dir {
|
||||
| Direction::Forward => "f",
|
||||
| Direction::Backward => "b",
|
||||
};
|
||||
|
||||
let not_found = || {
|
||||
err!(Request(NotFound(
|
||||
"Unable to find event from {} in direction {}",
|
||||
body.ts.get(),
|
||||
dir
|
||||
)))
|
||||
};
|
||||
|
||||
let Some((_, event)) = services
|
||||
.rooms
|
||||
.timeline
|
||||
.event_by_timestamp(room_id, body.ts, body.dir)
|
||||
.await
|
||||
else {
|
||||
return Err(not_found());
|
||||
};
|
||||
|
||||
if !services
|
||||
.rooms
|
||||
.state_accessor
|
||||
.user_can_see_event(sender_user, room_id, event.event_id())
|
||||
.await
|
||||
{
|
||||
return Err!(Request(Forbidden("You don't have permission to view this event.")));
|
||||
}
|
||||
|
||||
Ok(get_event_by_timestamp::v1::Response::new(
|
||||
event.event_id().to_owned(),
|
||||
event.origin_server_ts(),
|
||||
))
|
||||
}
|
||||
@@ -52,7 +52,6 @@ pub fn build(router: Router<State>, state: State) -> Router<State> {
|
||||
.ruma_route(&client::set_pushrule_actions_route)
|
||||
.ruma_route(&client::delete_pushrule_route)
|
||||
.ruma_route(&client::get_room_event_route)
|
||||
.ruma_route(&client::get_event_by_timestamp_route)
|
||||
.ruma_route(&client::get_room_aliases_route)
|
||||
.ruma_route(&client::get_filter_route)
|
||||
.ruma_route(&client::create_filter_route)
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
event::Event,
|
||||
pdu::{PduCount, PduEvent},
|
||||
},
|
||||
utils::{MutexMap, MutexMapGuard, ReadyExt, future::TryExtExt, stream::TryIgnore},
|
||||
utils::{MutexMap, MutexMapGuard, future::TryExtExt, stream::TryIgnore},
|
||||
warn,
|
||||
};
|
||||
use futures::{Future, Stream, StreamExt, TryStreamExt, pin_mut};
|
||||
use futures::{Future, Stream, TryStreamExt, pin_mut};
|
||||
use ruma::{
|
||||
CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, RoomId,
|
||||
api::Direction, events::room::encrypted::Relation,
|
||||
CanonicalJsonObject, EventId, OwnedEventId, OwnedRoomId, RoomId,
|
||||
events::room::encrypted::Relation,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
|
||||
@@ -272,72 +272,4 @@ pub fn pdus<'a>(
|
||||
) -> impl Stream<Item = Result<PdusIterItem>> + Send + 'a {
|
||||
self.db.pdus(room_id, from.unwrap_or_else(PduCount::min))
|
||||
}
|
||||
|
||||
async fn pdu_at_or_after(&self, room_id: &RoomId, count: PduCount) -> Option<PdusIterItem> {
|
||||
let pdus = self
|
||||
.pdus(room_id, Some(count.saturating_sub(1)))
|
||||
.ignore_err()
|
||||
.ready_filter(move |(at, _)| *at >= count);
|
||||
|
||||
pin_mut!(pdus);
|
||||
pdus.next().await
|
||||
}
|
||||
|
||||
async fn pdu_at_or_before(&self, room_id: &RoomId, count: PduCount) -> Option<PdusIterItem> {
|
||||
let pdus = self
|
||||
.pdus_rev(room_id, Some(count.saturating_add(1)))
|
||||
.ignore_err()
|
||||
.ready_filter(move |(at, _)| *at <= count);
|
||||
|
||||
pin_mut!(pdus);
|
||||
pdus.next().await
|
||||
}
|
||||
|
||||
pub async fn event_by_timestamp(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
ts: MilliSecondsSinceUnixEpoch,
|
||||
dir: Direction,
|
||||
) -> Option<PdusIterItem> {
|
||||
let first = self.pdu_at_or_after(room_id, PduCount::min()).await?.0;
|
||||
let last = self.pdu_at_or_before(room_id, PduCount::max()).await?.0;
|
||||
let mut low = first.into_signed();
|
||||
let mut high = last.into_signed();
|
||||
let mut result = None;
|
||||
|
||||
match dir {
|
||||
| Direction::Forward =>
|
||||
while low <= high {
|
||||
let count = PduCount::from_signed(low.midpoint(high));
|
||||
let Some((at, pdu)) = self.pdu_at_or_after(room_id, count).await else {
|
||||
high = count.into_signed().saturating_sub(1);
|
||||
continue;
|
||||
};
|
||||
|
||||
if pdu.origin_server_ts() >= ts {
|
||||
result = Some((at, pdu));
|
||||
high = at.into_signed().saturating_sub(1);
|
||||
} else {
|
||||
low = at.into_signed().saturating_add(1);
|
||||
}
|
||||
},
|
||||
| Direction::Backward =>
|
||||
while low <= high {
|
||||
let count = PduCount::from_signed(low.midpoint(high));
|
||||
let Some((at, pdu)) = self.pdu_at_or_before(room_id, count).await else {
|
||||
low = count.into_signed().saturating_add(1);
|
||||
continue;
|
||||
};
|
||||
|
||||
if pdu.origin_server_ts() <= ts {
|
||||
result = Some((at, pdu));
|
||||
low = at.into_signed().saturating_add(1);
|
||||
} else {
|
||||
high = at.into_signed().saturating_sub(1);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user