From f0291719485854c8fb02efb9870e364405bc1afb Mon Sep 17 00:00:00 2001 From: nazeh Date: Fri, 27 Sep 2024 12:53:11 +0300 Subject: [PATCH] feat(homeserver): add DEFAULT_LIST_LIMIT and DEFAULT_MAX_LIST_LIMIT --- pubky-homeserver/src/database.rs | 1 - .../src/database/tables/events.rs | 50 +++++++++++++++++ pubky-homeserver/src/routes/feed.rs | 53 ++----------------- 3 files changed, 54 insertions(+), 50 deletions(-) diff --git a/pubky-homeserver/src/database.rs b/pubky-homeserver/src/database.rs index b655a45..9eb291f 100644 --- a/pubky-homeserver/src/database.rs +++ b/pubky-homeserver/src/database.rs @@ -9,7 +9,6 @@ pub mod tables; use tables::{Tables, TABLES_COUNT}; -pub const MAX_LIST_LIMIT: u16 = 100; pub const DEFAULT_MAP_SIZE: usize = 10995116277760; // 10TB (not = disk-space used) #[derive(Debug, Clone)] diff --git a/pubky-homeserver/src/database/tables/events.rs b/pubky-homeserver/src/database/tables/events.rs index cf82e18..c04554b 100644 --- a/pubky-homeserver/src/database/tables/events.rs +++ b/pubky-homeserver/src/database/tables/events.rs @@ -10,6 +10,8 @@ use heed::{ use postcard::{from_bytes, to_allocvec}; use serde::{Deserialize, Serialize}; +use crate::database::DB; + /// Event [Timestamp] base32 => Encoded event. pub type EventsTable = Database; @@ -56,3 +58,51 @@ impl Event { } } } + +const MAX_LIST_LIMIT: u16 = 1000; +const DEFAULT_LIST_LIMIT: u16 = 100; + +impl DB { + pub fn list_events( + &self, + limit: Option, + cursor: Option<&str>, + ) -> anyhow::Result> { + let txn = self.env.read_txn()?; + + let limit = limit.unwrap_or(DEFAULT_LIST_LIMIT).min(MAX_LIST_LIMIT); + + let mut cursor = cursor.unwrap_or("0000000000000"); + + // Cursor smaller than 13 character is invalid + // TODO: should we send an error instead? + if cursor.len() < 13 { + cursor = "0000000000000" + } + + let mut result: Vec = vec![]; + let mut next_cursor = cursor.to_string(); + + for _ in 0..limit { + match self.tables.events.get_greater_than(&txn, &next_cursor)? { + Some((timestamp, event_bytes)) => { + let event = Event::deserialize(event_bytes)?; + + let line = format!("{} {}", event.operation(), event.url()); + next_cursor = timestamp.to_string(); + + result.push(line); + } + None => break, + }; + } + + if !result.is_empty() { + result.push(format!("cursor: {next_cursor}")) + } + + txn.commit()?; + + Ok(result) + } +} diff --git a/pubky-homeserver/src/routes/feed.rs b/pubky-homeserver/src/routes/feed.rs index bd426f3..0afe504 100644 --- a/pubky-homeserver/src/routes/feed.rs +++ b/pubky-homeserver/src/routes/feed.rs @@ -7,61 +7,16 @@ use axum::{ response::IntoResponse, }; -use crate::{ - database::{tables::events::Event, MAX_LIST_LIMIT}, - error::Result, - server::AppState, -}; +use crate::{error::Result, server::AppState}; pub async fn feed( State(state): State, Query(params): Query>, ) -> Result { - let txn = state.db.env.read_txn()?; + let limit = params.get("limit").and_then(|l| l.parse::().ok()); + let cursor = params.get("cursor").map(|c| c.as_str()); - let limit = params - .get("limit") - .and_then(|l| l.parse::().ok()) - .unwrap_or(MAX_LIST_LIMIT) - .min(MAX_LIST_LIMIT); - - let mut cursor = params - .get("cursor") - .map(|c| c.as_str()) - .unwrap_or("0000000000000"); - - // Guard against bad cursor - if cursor.len() < 13 { - cursor = "0000000000000" - } - - let mut result: Vec = vec![]; - let mut next_cursor = cursor.to_string(); - - for _ in 0..limit { - match state - .db - .tables - .events - .get_greater_than(&txn, &next_cursor)? - { - Some((timestamp, event_bytes)) => { - let event = Event::deserialize(event_bytes)?; - - let line = format!("{} {}", event.operation(), event.url()); - next_cursor = timestamp.to_string(); - - result.push(line); - } - None => break, - }; - } - - if !result.is_empty() { - result.push(format!("cursor: {next_cursor}")) - } - - txn.commit()?; + let result = state.db.list_events(limit, cursor)?; Ok(Response::builder() .status(StatusCode::OK)