mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-11-15 13:16:56 +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 parent
32a36f56c7
commit
ffcf152016
5 files changed
+5
-138
No files matched your search
@@ -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 create;
|
|||||||
mod event;
|
mod event;
|
||||||
mod initial_sync;
|
mod initial_sync;
|
||||||
mod summary;
|
mod summary;
|
||||||
mod timestamp_to_event;
|
|
||||||
mod upgrade;
|
mod upgrade;
|
||||||
|
|
||||||
pub(crate) use self::{
|
pub(crate) use self::{
|
||||||
aliases::get_room_aliases_route, create::create_room_route, event::get_room_event_route,
|
aliases::get_room_aliases_route, create::create_room_route, event::get_room_event_route,
|
||||||
initial_sync::room_initial_sync_route, summary::get_room_summary,
|
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::set_pushrule_actions_route)
|
||||||
.ruma_route(&client::delete_pushrule_route)
|
.ruma_route(&client::delete_pushrule_route)
|
||||||
.ruma_route(&client::get_room_event_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_room_aliases_route)
|
||||||
.ruma_route(&client::get_filter_route)
|
.ruma_route(&client::get_filter_route)
|
||||||
.ruma_route(&client::create_filter_route)
|
.ruma_route(&client::create_filter_route)
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ use conduwuit_core::{
|
|||||||
event::Event,
|
event::Event,
|
||||||
pdu::{PduCount, PduEvent},
|
pdu::{PduCount, PduEvent},
|
||||||
},
|
},
|
||||||
utils::{MutexMap, MutexMapGuard, ReadyExt, future::TryExtExt, stream::TryIgnore},
|
utils::{MutexMap, MutexMapGuard, future::TryExtExt, stream::TryIgnore},
|
||||||
warn,
|
warn,
|
||||||
};
|
};
|
||||||
use futures::{Future, Stream, StreamExt, TryStreamExt, pin_mut};
|
use futures::{Future, Stream, TryStreamExt, pin_mut};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, RoomId,
|
CanonicalJsonObject, EventId, OwnedEventId, OwnedRoomId, RoomId,
|
||||||
api::Direction, events::room::encrypted::Relation,
|
events::room::encrypted::Relation,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -272,72 +272,4 @@ impl Service {
|
|||||||
) -> impl Stream<Item = Result<PdusIterItem>> + Send + 'a {
|
) -> impl Stream<Item = Result<PdusIterItem>> + Send + 'a {
|
||||||
self.db.pdus(room_id, from.unwrap_or_else(PduCount::min))
|
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