mirror of
https://github.com/aljazceru/pubky-core.git
synced 2026-01-30 11:24:31 +01:00
feat(homeserver): add DEFAULT_LIST_LIMIT and DEFAULT_MAX_LIST_LIMIT
This commit is contained in:
@@ -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)]
|
||||
|
||||
@@ -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<Str, Bytes>;
|
||||
|
||||
@@ -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<u16>,
|
||||
cursor: Option<&str>,
|
||||
) -> anyhow::Result<Vec<String>> {
|
||||
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<String> = 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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<AppState>,
|
||||
Query(params): Query<HashMap<String, String>>,
|
||||
) -> Result<impl IntoResponse> {
|
||||
let txn = state.db.env.read_txn()?;
|
||||
let limit = params.get("limit").and_then(|l| l.parse::<u16>().ok());
|
||||
let cursor = params.get("cursor").map(|c| c.as_str());
|
||||
|
||||
let limit = params
|
||||
.get("limit")
|
||||
.and_then(|l| l.parse::<u16>().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<String> = 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)
|
||||
|
||||
Reference in New Issue
Block a user