Prune telemetry entries, remove uplot comments, format code

This commit is contained in:
Gnome Adrift
2026-04-01 13:02:02 -07:00
committed by Jack Kingsman
parent c808f0930b
commit 967dd05fad
7 changed files with 35 additions and 11 deletions

View File

@@ -834,7 +834,6 @@ async def stop_periodic_advert():
logger.info("Stopped periodic advertisement")
# Prevents reboot-loop: once we've rebooted to fix clock skew this session,
# don't do it again (the hardware RTC case can't be fixed by reboot).
_clock_reboot_attempted: bool = False

View File

@@ -1,10 +1,17 @@
import json
import logging
import time
from app.database import db
logger = logging.getLogger(__name__)
# Maximum age for telemetry history entries (30 days)
_MAX_AGE_SECONDS = 30 * 86400
# Maximum entries to keep per repeater (sanity cap)
_MAX_ENTRIES_PER_REPEATER = 1000
class RepeaterTelemetryRepository:
@staticmethod
@@ -13,7 +20,7 @@ class RepeaterTelemetryRepository:
timestamp: int,
data: dict,
) -> None:
"""Insert a telemetry history row with the full status snapshot as JSON."""
"""Insert a telemetry history row and prune stale entries."""
await db.conn.execute(
"""
INSERT INTO repeater_telemetry_history
@@ -22,6 +29,28 @@ class RepeaterTelemetryRepository:
""",
(public_key, timestamp, json.dumps(data)),
)
# Prune entries older than 30 days
cutoff = int(time.time()) - _MAX_AGE_SECONDS
await db.conn.execute(
"DELETE FROM repeater_telemetry_history WHERE public_key = ? AND timestamp < ?",
(public_key, cutoff),
)
# Cap at _MAX_ENTRIES_PER_REPEATER (keep newest)
await db.conn.execute(
"""
DELETE FROM repeater_telemetry_history
WHERE public_key = ? AND id NOT IN (
SELECT id FROM repeater_telemetry_history
WHERE public_key = ?
ORDER BY timestamp DESC
LIMIT ?
)
""",
(public_key, public_key, _MAX_ENTRIES_PER_REPEATER),
)
await db.conn.commit()
@staticmethod

View File

@@ -1,9 +1,7 @@
import logging
import time
from typing import TYPE_CHECKING
from fastapi import APIRouter, HTTPException
from meshcore import EventType
from app.dependencies import require_connected
from app.models import (

View File

@@ -123,9 +123,7 @@ export function TelemetryHistoryPane({
tick={{ fontSize: 10, fill: 'hsl(var(--muted-foreground))' }}
tickLine={false}
axisLine={false}
tickFormatter={(v) =>
metric === 'uptime_seconds' ? formatUptime(v) : `${v}`
}
tickFormatter={(v) => (metric === 'uptime_seconds' ? formatUptime(v) : `${v}`)}
/>
<RechartsTooltip
{...TOOLTIP_STYLE}
@@ -139,7 +137,8 @@ export function TelemetryHistoryPane({
formatter={(value: any, name: any) => {
const numVal = typeof value === 'number' ? value : Number(value);
const display = metric === 'uptime_seconds' ? formatUptime(numVal) : `${value}`;
const suffix = metric === 'uptime_seconds' ? '' : config.unit ? ` ${config.unit}` : '';
const suffix =
metric === 'uptime_seconds' ? '' : config.unit ? ` ${config.unit}` : '';
const label =
metric === 'packets'
? name === 'packets_received'

View File

@@ -8,7 +8,7 @@ class ResizeObserver {
globalThis.ResizeObserver = ResizeObserver;
// uPlot calls matchMedia at import time for DPI detection
// Several components call matchMedia at import time for responsive detection
if (typeof globalThis.matchMedia === 'undefined') {
Object.defineProperty(globalThis, 'matchMedia', {
value: (query: string) => ({

View File

@@ -473,7 +473,7 @@ export interface PaneState {
export interface TelemetryHistoryEntry {
timestamp: number;
data: RepeaterStatusResponse;
data: Record<string, number>;
}
export interface TraceResponse {

View File

@@ -1,6 +1,5 @@
"""Tests for repeater telemetry history: repository CRUD and embedded status response."""
import json
import time
import pytest