hashiverse_server_lib/server/post_bundle_caching_shared.rs
1//! # Shared types and tuning constants for the bundle caches
2//!
3//! The common pieces used by both
4//! [`crate::server::post_bundle_caching`] and
5//! [`crate::server::post_bundle_feedback_caching`]:
6//!
7//! - [`CachedBundle`] — bytes + optional `expires_at`. *Live* (still-mutating)
8//! bundles carry an expiry; *sealed* (immutable past-tense) bundles do not and stay
9//! cached until evicted by LRU pressure.
10//! - [`GetCacheResult`] — lookup outcome: `Miss`, `Hit`, `HitAndIssueToken` (the
11//! latter triggering [`hashiverse_lib::protocol::payload::payload::CacheRequestTokenV1`]
12//! emission from the caller).
13//! - `CACHE_LOCATION_TTI` (60 s) and `CACHE_HIT_THRESHOLD` (10) — the tuning that
14//! decides when a bundle is "hot enough" to justify asking callers to help replicate
15//! it further.
16
17use bytes::Bytes;
18use hashiverse_lib::protocol::payload::payload::CacheRequestTokenV1;
19use hashiverse_lib::tools::time::{DurationMillis, TimeMillis, MILLIS_IN_SECOND};
20use std::time::Duration;
21
22/// TTI for all cache entries: if a location_id hasn't been queried for a while, evict it entirely.
23pub const CACHE_LOCATION_TTI: Duration = Duration::from_secs(60);
24
25/// Number of hits on a placeholder entry before the server issues a CacheRequestToken.
26/// Essentially: have we had this many requests in the last `CACHE_LOCATION_TTI`? If so, start caching.
27pub const CACHE_HIT_THRESHOLD: u32 = 10;
28
29/// How long a CacheRequestToken is valid for (client must upload within this window).
30pub const CACHE_REQUEST_TOKEN_TTL_DURATION_MILLIS: DurationMillis = MILLIS_IN_SECOND.const_mul(30);
31pub const CACHE_REQUEST_TOKEN_TTL_DURATION: Duration = Duration::from_millis(CACHE_REQUEST_TOKEN_TTL_DURATION_MILLIS.0 as u64);
32
33/// One bundle (from one originator peer) held in the cache.
34pub struct CachedBundle {
35 pub bytes: Bytes,
36 /// `None` for sealed bundles (never individually stale; only location-level TTI applies).
37 /// `Some(server_time + 5min)` for live bundles (checked manually on read).
38 pub expires_at: Option<TimeMillis>,
39}
40
41impl CachedBundle {
42 pub fn is_stale(&self, now: TimeMillis) -> bool {
43 match self.expires_at {
44 None => false,
45 Some(exp) => now >= exp,
46 }
47 }
48}
49
50/// Result returned to the dispatch handler by either cache's `on_get`.
51pub struct GetCacheResult {
52 /// Fresh cached bundles filtered by `already_retrieved_peer_ids`.
53 pub cached_items: Vec<Bytes>,
54 /// Issued when the server wants the client to upload after its walk.
55 pub cache_request_token: Option<CacheRequestTokenV1>,
56}