More fixes

This commit is contained in:
Andras Schmelczer 2026-03-18 22:46:08 +00:00
parent 15fa09430b
commit 6b12e21d50
54 changed files with 1665 additions and 630 deletions

View file

@ -1,13 +1,62 @@
use std::sync::Arc;
use std::time::Duration;
use std::time::{Duration, Instant};
use metrics::gauge;
use parking_lot::RwLock;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use tracing::{info, warn};
use crate::state::AppState;
/// Cache TTL for the superuser token. PocketBase superuser JWTs are valid for
/// ~14 days by default, so 10 minutes is very conservative while eliminating
/// nearly all redundant auth requests (metrics poller, newsletter, invites, etc.).
const SUPERUSER_TOKEN_TTL_SECS: u64 = 600;
pub struct SuperuserTokenCache {
token: RwLock<Option<(String, Instant)>>,
}
impl SuperuserTokenCache {
pub fn new() -> Self {
Self {
token: RwLock::new(None),
}
}
}
/// Get a cached superuser token, or authenticate fresh if expired/missing.
pub async fn get_superuser_token(state: &AppState) -> anyhow::Result<String> {
// Check cache first (read lock — cheap, non-blocking for other readers)
{
let cached = state.superuser_token_cache.token.read();
if let Some((token, created)) = cached.as_ref() {
if created.elapsed().as_secs() < SUPERUSER_TOKEN_TTL_SECS {
return Ok(token.clone());
}
}
}
// Cache miss or expired — fetch a fresh token
let pb_url = state.pocketbase_url.trim_end_matches('/');
let token = auth_superuser(
&state.http_client,
pb_url,
&state.pocketbase_admin_email,
&state.pocketbase_admin_password,
)
.await?;
// Store in cache
{
let mut cached = state.superuser_token_cache.token.write();
*cached = Some((token.clone(), Instant::now()));
}
Ok(token)
}
#[derive(Deserialize)]
struct AuthResponse {
token: String,
@ -775,21 +824,14 @@ pub fn start_metrics_poller(shared: Arc<crate::state::SharedState>) {
}
async fn poll_pocketbase_counts(state: &AppState) {
let pb_url = state.pocketbase_url.trim_end_matches('/');
let token = match auth_superuser(
&state.http_client,
pb_url,
&state.pocketbase_admin_email,
&state.pocketbase_admin_password,
)
.await
{
let token = match get_superuser_token(state).await {
Ok(tk) => tk,
Err(err) => {
warn!("PocketBase metrics poll auth failed: {err}");
return;
}
};
let pb_url = state.pocketbase_url.trim_end_matches('/');
// Simple collection counts
for (collection, metric_name) in [