Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions nodelite-server/src/load_test/scenarios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,22 @@ async fn run_reconnect_storm_scenario(node_count: usize) -> Result<StormScenario
);
}

// 输出 token 缓存统计 (issue #306)
let cache_hits = server.registry.token_cache_hits();
let cache_misses = server.registry.token_cache_misses();
let cache_hit_rate = server.registry.token_cache_hit_rate();
let registry_revision = server.registry.registry_revision();
println!(
"STORM_CACHE_STATS nodes={} cycles={} sessions={} cache_hits={} cache_misses={} hit_rate={:.2}% registry_revision={}",
node_count,
LOAD_TEST_STORM_CYCLES,
node_count * LOAD_TEST_STORM_CYCLES,
cache_hits,
cache_misses,
cache_hit_rate,
registry_revision
);

server.shutdown().await?;

Ok(StormScenarioResult {
Expand Down
3 changes: 3 additions & 0 deletions nodelite-server/src/load_test/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub(super) struct TestServer {
pub(super) addr: SocketAddr,
pub(super) shared: SharedState,
pub(super) history: HistoryStore,
pub(super) registry: crate::registry::NodeRegistry,
shutdown_tx: Option<tokio::sync::oneshot::Sender<()>>,
server_handle: JoinHandle<Result<(), std::io::Error>>,
temp_dir: PathBuf,
Expand Down Expand Up @@ -93,6 +94,7 @@ impl TestServer {
)
.await?;
let history = state.history.clone();
let registry = state.registry.clone();

let shared = state.shared.clone();
let protected_routes = Router::new()
Expand Down Expand Up @@ -126,6 +128,7 @@ impl TestServer {
addr,
shared,
history,
registry,
shutdown_tx: Some(shutdown_tx),
server_handle,
temp_dir,
Expand Down
3 changes: 3 additions & 0 deletions nodelite-server/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,9 @@ pub struct NodeRegistry {
token_verify_limiter: Arc<Semaphore>,
/// Token 验证结果缓存:减少重连场景的 Argon2id 开销。
token_cache: Arc<ParkingLotMutex<LruCache<TokenCacheKey, TokenCacheEntry>>>,
/// Token 缓存诊断计数器 (issue #306)。
token_cache_hits: Arc<AtomicU64>,
token_cache_misses: Arc<AtomicU64>,
#[cfg(test)]
token_verify_probe: Option<Arc<TokenVerifyProbe>>,
}
Expand Down
8 changes: 6 additions & 2 deletions nodelite-server/src/registry/auth.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::sync::Arc;
use std::sync::atomic::Ordering;
#[cfg(test)]
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::atomic::AtomicUsize;
#[cfg(test)]
use std::time::Duration;
use std::time::Instant;
Expand Down Expand Up @@ -127,6 +128,7 @@ impl NodeRegistry {
if let Some(entry) = cache.get(&cache_key) {
let age = entry.cached_at.elapsed();
if age < TOKEN_CACHE_TTL {
self.token_cache_hits.fetch_add(1, Ordering::Relaxed);
return Ok(entry.verified);
}
// TTL 过期,移除旧条目
Expand Down Expand Up @@ -157,12 +159,14 @@ impl NodeRegistry {
if let Some(entry) = cache.get(&cache_key) {
let age = entry.cached_at.elapsed();
if age < TOKEN_CACHE_TTL {
self.token_cache_hits.fetch_add(1, Ordering::Relaxed);
return Ok(entry.verified);
}
}
}

// 执行实际的 Argon2id 验证
// 缓存未命中,执行实际的 Argon2id 验证
self.token_cache_misses.fetch_add(1, Ordering::Relaxed);
let input = input.to_string();
let token_hash = token_hash.to_string();
#[cfg(test)]
Expand Down
27 changes: 27 additions & 0 deletions nodelite-server/src/registry/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ impl NodeRegistry {
token_cache: Arc::new(ParkingLotMutex::new(LruCache::new(
std::num::NonZeroUsize::new(TOKEN_CACHE_CAPACITY).expect("cache capacity > 0"),
))),
token_cache_hits: Arc::new(AtomicU64::new(0)),
token_cache_misses: Arc::new(AtomicU64::new(0)),
#[cfg(test)]
token_verify_probe: None,
})
Expand All @@ -50,6 +52,31 @@ impl NodeRegistry {
self.registry_revision.load(Ordering::Acquire)
}

/// Token 缓存命中计数(累积值,issue #306)。
#[cfg(test)]
pub fn token_cache_hits(&self) -> u64 {
self.token_cache_hits.load(Ordering::Relaxed)
}

/// Token 缓存未命中计数(累积值,issue #306)。
#[cfg(test)]
pub fn token_cache_misses(&self) -> u64 {
self.token_cache_misses.load(Ordering::Relaxed)
}

/// Token 缓存命中率(百分比,issue #306)。
#[cfg(test)]
pub fn token_cache_hit_rate(&self) -> f64 {
let hits = self.token_cache_hits() as f64;
let misses = self.token_cache_misses() as f64;
let total = hits + misses;
if total == 0.0 {
0.0
} else {
(hits / total) * 100.0
}
}

/// 刷新节点的 Token:生成新明文 token, 哈希入库,代次 +1, 延长过期时间。
/// 返回 (new_plaintext_token, expires_at, new_generation)。明文只在
/// 进程内存里短暂存在,从这里被传递给 WS 端发送给 agent。
Expand Down
Loading