Add settings-configurable cap on logs kept in memory (ticket 026)
Settings.max_logs (default None = unlimited) is pushed to the engine via a new EngineMessage::SetMaxLogs, enforced on every ingest and whenever the setting changes at runtime (no restart required). Eviction drops the oldest (lowest-sequence) logs; sequence numbering isn't renumbered and buckets already derived from an evicted log are left in place. Exposed via PATCH /api/settings (max_logs: number | null) and a NavMenu numeric field (blank = unlimited). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
aaa5596030
commit
1d0f324c43
+22
-3
@@ -194,6 +194,8 @@ impl From<&CssEntry> for CssEntryDto {
|
||||
pub struct SettingsDto {
|
||||
pub color_scheme: ColorScheme,
|
||||
pub active_profile: Option<String>,
|
||||
/// `None` means unlimited (ticket 026).
|
||||
pub max_logs: Option<usize>,
|
||||
}
|
||||
|
||||
impl From<&Settings> for SettingsDto {
|
||||
@@ -201,16 +203,33 @@ impl From<&Settings> for SettingsDto {
|
||||
SettingsDto {
|
||||
color_scheme: settings.color_scheme,
|
||||
active_profile: settings.profiles.active_profile.clone(),
|
||||
max_logs: settings.max_logs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Request body for `PATCH /api/settings`. Only `color_scheme` is
|
||||
/// updatable for now; `None` leaves the current value untouched (so a
|
||||
/// partial body doesn't reset other fields).
|
||||
/// Request body for `PATCH /api/settings`. `color_scheme`: `None` leaves the
|
||||
/// current value untouched. `max_logs`: distinguishes "field omitted" (leave
|
||||
/// unchanged, outer `None`) from "field present" (inner `Option<usize>`
|
||||
/// applied verbatim — `null` clears the cap back to unlimited, a number sets
|
||||
/// it), via `deserialize_double_option`.
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct UpdateSettingsRequest {
|
||||
pub color_scheme: Option<ColorScheme>,
|
||||
#[serde(default, deserialize_with = "deserialize_double_option")]
|
||||
pub max_logs: Option<Option<usize>>,
|
||||
}
|
||||
|
||||
/// Distinguishes a missing JSON field (outer `None`, via `#[serde(default)]`
|
||||
/// short-circuiting before this runs) from a present `null` (`Some(None)`)
|
||||
/// or present value (`Some(Some(value))`) — plain `Option<Option<T>>` can't
|
||||
/// tell "absent" and "explicit null" apart on its own.
|
||||
fn deserialize_double_option<'de, D, T>(deserializer: D) -> Result<Option<Option<T>>, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
T: Deserialize<'de>,
|
||||
{
|
||||
Option::<T>::deserialize(deserializer).map(Some)
|
||||
}
|
||||
|
||||
/// Summary of one profile for `GET /api/settings/profiles` (ticket 011):
|
||||
|
||||
Reference in New Issue
Block a user