revert feat: Add timestamp to event endpoint

This implementation unfortunately resulted in resource exhaustion when run on some rooms.
This commit is contained in:
Jade
2026-09-16 13:05:45 +00:00
committed by Ellis Git
parent 32a36f56c7
commit ffcf152016
5 changed files with 5 additions and 138 deletions
@@ -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.
+1 -2
View File
@@ -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,
};
-62
View File
@@ -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(),
))
}
-1
View File
@@ -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)
+4 -72
View File
@@ -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
}
}