[sgl-router] refactor - move policy-required states under src/state (#40272)
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
acd20a516e
commit
4a9dc5c4af
@@ -90,7 +90,8 @@ async fn static_urls_pd_role_resolved_end_to_end() {
|
||||
use axum::{routing::get, Json, Router};
|
||||
use serde_json::json;
|
||||
use sgl_router::config::{
|
||||
ActiveLoadConfig, Config, DiscoveryBackend, ObservabilityConfig, ProxyConfig, ServerConfig,
|
||||
Config, DiscoveryBackend, InflightLoadConfig, ObservabilityConfig, ProxyConfig,
|
||||
ServerConfig,
|
||||
};
|
||||
use sgl_router::discovery::{spawn_discovery, WorkerId};
|
||||
use sgl_router::workers::{manager, WorkerRegistry};
|
||||
@@ -146,7 +147,7 @@ async fn static_urls_pd_role_resolved_end_to_end() {
|
||||
urls: vec![url.clone()],
|
||||
}),
|
||||
proxy: ProxyConfig::default(),
|
||||
active_load: ActiveLoadConfig::default(),
|
||||
router_inflight_load: InflightLoadConfig::default(),
|
||||
};
|
||||
|
||||
let registry = Arc::new(WorkerRegistry::default());
|
||||
|
||||
@@ -5,10 +5,8 @@ use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
|
||||
use sgl_kv_indexer::PrefixOutcome;
|
||||
use sgl_router::policies::kv_events::{
|
||||
compute_block_hashes, BlockSizeOracle, HashTree, KvWorkerId,
|
||||
};
|
||||
use sgl_router::policies::prefix_provider::RadixTreePrefixProvider;
|
||||
use sgl_router::state::kv_events::{compute_block_hashes, BlockSizeOracle, HashTree, KvWorkerId};
|
||||
|
||||
#[test]
|
||||
fn radix_tree_reports_contiguous_prefix_depth_per_worker() {
|
||||
|
||||
@@ -12,8 +12,10 @@ use sgl_router::policies::decode::{
|
||||
resolve_decode_with_capacity_fallback, DecodePolicy, DecodePowerOfTwoPolicy,
|
||||
DecodeSelectionContext, LegacyHostAffinityDecodePolicy,
|
||||
};
|
||||
use sgl_router::policies::engine_load::{EngineLoadSnapshot, NativeCacheWorkerLoad};
|
||||
use sgl_router::policies::SelectionProposal;
|
||||
use sgl_router::state::load_monitor::engine_reported_load::{
|
||||
EngineReportedLoadSnapshot, EngineReportedSchedulingLoad,
|
||||
};
|
||||
use sgl_router::workers::Worker;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::atomic::Ordering;
|
||||
@@ -30,15 +32,15 @@ fn worker(id: &str) -> Arc<Worker> {
|
||||
}))
|
||||
}
|
||||
|
||||
fn snapshot(entries: &[(&Arc<Worker>, u64, u64, u64, u64)]) -> EngineLoadSnapshot {
|
||||
EngineLoadSnapshot::from_native_cache_workers(
|
||||
fn snapshot(entries: &[(&Arc<Worker>, u64, u64, u64, u64)]) -> EngineReportedLoadSnapshot {
|
||||
EngineReportedLoadSnapshot::from_native_cache_workers(
|
||||
7,
|
||||
entries
|
||||
.iter()
|
||||
.map(|(worker, running, waiting, used, capacity)| {
|
||||
(
|
||||
worker.url.clone(),
|
||||
NativeCacheWorkerLoad {
|
||||
EngineReportedSchedulingLoad {
|
||||
num_running_reqs: *running,
|
||||
num_waiting_reqs: *waiting,
|
||||
num_waiting_uncached_tokens: *waiting,
|
||||
|
||||
@@ -12,15 +12,15 @@
|
||||
//! and the idlest at 1.0, so every assertion below holds either way.
|
||||
|
||||
use sgl_router::discovery::{ModelId, WorkerId, WorkerMode, WorkerSpec};
|
||||
use sgl_router::policies::engine_load::{EngineLoadSnapshot, EngineWorkerLoad};
|
||||
use sgl_router::policies::kv_events::{
|
||||
compute_block_hashes, BlockSizeOracle, HashTree, KvWorkerId,
|
||||
};
|
||||
use sgl_router::policies::load_based::LoadBasedPolicy;
|
||||
use sgl_router::policies::scoring::{
|
||||
prefix_cache::PrefixCachePolicy, FusedScorePolicy, ScorePolicy,
|
||||
};
|
||||
use sgl_router::policies::{Policy, SelectionContext};
|
||||
use sgl_router::state::kv_events::{compute_block_hashes, BlockSizeOracle, HashTree, KvWorkerId};
|
||||
use sgl_router::state::load_monitor::engine_reported_load::{
|
||||
EngineReportedLoadSnapshot, EngineReportedWorkerLoad,
|
||||
};
|
||||
use sgl_router::workers::Worker;
|
||||
use std::{collections::HashMap, sync::Arc, time::Instant};
|
||||
|
||||
@@ -82,12 +82,12 @@ fn fused_load_based_term_uses_the_request_snapshot() {
|
||||
let ws = vec![worker("w0"), worker("w1")];
|
||||
// Local counters changed after the request snapshot and prefer w0.
|
||||
let _after_snapshot: Vec<_> = (0..10).map(|_| ws[1].load_guard()).collect();
|
||||
let snapshot = EngineLoadSnapshot::from_workers(
|
||||
let snapshot = EngineReportedLoadSnapshot::from_workers(
|
||||
29,
|
||||
HashMap::from([
|
||||
(
|
||||
ws[0].url.clone(),
|
||||
EngineWorkerLoad {
|
||||
EngineReportedWorkerLoad {
|
||||
num_running_reqs: 50,
|
||||
num_waiting_reqs: 0,
|
||||
num_tokens: 0,
|
||||
@@ -97,7 +97,7 @@ fn fused_load_based_term_uses_the_request_snapshot() {
|
||||
),
|
||||
(
|
||||
ws[1].url.clone(),
|
||||
EngineWorkerLoad {
|
||||
EngineReportedWorkerLoad {
|
||||
num_running_reqs: 1,
|
||||
num_waiting_reqs: 0,
|
||||
num_tokens: 0,
|
||||
@@ -123,12 +123,12 @@ fn fused_load_based_term_uses_the_request_snapshot() {
|
||||
fn score_policy_forwards_the_request_snapshot_to_load_based() {
|
||||
let ws = vec![worker("w0"), worker("w1")];
|
||||
let _after_snapshot: Vec<_> = (0..10).map(|_| ws[1].load_guard()).collect();
|
||||
let snapshot = EngineLoadSnapshot::from_workers(
|
||||
let snapshot = EngineReportedLoadSnapshot::from_workers(
|
||||
31,
|
||||
HashMap::from([
|
||||
(
|
||||
ws[0].url.clone(),
|
||||
EngineWorkerLoad {
|
||||
EngineReportedWorkerLoad {
|
||||
num_running_reqs: 50,
|
||||
num_waiting_reqs: 0,
|
||||
num_tokens: 0,
|
||||
@@ -138,7 +138,7 @@ fn score_policy_forwards_the_request_snapshot_to_load_based() {
|
||||
),
|
||||
(
|
||||
ws[1].url.clone(),
|
||||
EngineWorkerLoad {
|
||||
EngineReportedWorkerLoad {
|
||||
num_running_reqs: 1,
|
||||
num_waiting_reqs: 0,
|
||||
num_tokens: 0,
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
//! whatever fixture is checked in.
|
||||
|
||||
use serde::Deserialize;
|
||||
use sgl_router::policies::kv_events::compute_block_hashes;
|
||||
use sgl_router::state::kv_events::compute_block_hashes;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
//! Concurrent-mutation stress test for `HashTree`.
|
||||
//!
|
||||
//! The inline tests in `policies::kv_events::tree` are all
|
||||
//! The inline tests in `state::kv_events::tree` are all
|
||||
//! single-threaded. Under production load, multiple worker subscribers
|
||||
//! drive `insert` / `remove` / `clear_worker` against the same tree from
|
||||
//! tokio worker threads while the chat handler simultaneously calls
|
||||
@@ -25,7 +25,7 @@
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use sgl_router::policies::kv_events::{HashTree, KvWorkerId};
|
||||
use sgl_router::state::kv_events::{HashTree, KvWorkerId};
|
||||
|
||||
fn worker(i: usize) -> KvWorkerId {
|
||||
KvWorkerId {
|
||||
|
||||
@@ -22,8 +22,8 @@ use std::time::Duration;
|
||||
|
||||
use zeromq::SocketSend;
|
||||
|
||||
use sgl_router::policies::kv_events::discovery::EventConfig;
|
||||
use sgl_router::policies::kv_events::{compute_block_hashes, KvEventIndex, KvWorkerId};
|
||||
use sgl_router::state::kv_events::discovery::EventConfig;
|
||||
use sgl_router::state::kv_events::{compute_block_hashes, KvEventIndex, KvWorkerId};
|
||||
|
||||
use super::zmq_helpers::{
|
||||
build_multipart, encode_block_stored_event, encode_event_batch, make_pub_bound,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// SPDX-FileCopyrightText: Copyright (c) 2026 The SGLang Authors
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
//! Shared ZMQ wire-format helpers for the `policies::kv_events` component
|
||||
//! Shared ZMQ wire-format helpers for the `state::kv_events` component
|
||||
//! tests. Encodes events in the same msgspec layout SGLang emits, builds
|
||||
//! the two-frame `[seq, payload]` ZMQ message a real publisher sends, and
|
||||
//! binds a loopback PUB socket on an OS-assigned port.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use serde::Deserialize;
|
||||
use sgl_router::config::{
|
||||
ActiveLoadConfig, Config, DiscoveryBackend, ModelConfig, ObservabilityConfig, PolicyKind,
|
||||
Config, DiscoveryBackend, InflightLoadConfig, ModelConfig, ObservabilityConfig, PolicyKind,
|
||||
ProxyConfig, ServerConfig, StaticUrlsDiscoveryConfig,
|
||||
};
|
||||
use sgl_router::discovery::ModelId;
|
||||
@@ -128,7 +128,7 @@ fn registry(model_id: &str, tokenizer_path: PathBuf) -> TokenizerRegistry {
|
||||
urls: vec!["http://placeholder:0".into()],
|
||||
}),
|
||||
proxy: ProxyConfig::default(),
|
||||
active_load: ActiveLoadConfig::default(),
|
||||
router_inflight_load: InflightLoadConfig::default(),
|
||||
};
|
||||
TokenizerRegistry::load_from_config(&cfg).unwrap()
|
||||
}
|
||||
|
||||
@@ -131,17 +131,17 @@ fn load_guard_decrements_on_panic_unwind() {
|
||||
model_ids: vec![ModelId("m".into())],
|
||||
bootstrap_port: None,
|
||||
}));
|
||||
assert_eq!(w.active_load(), 0);
|
||||
assert_eq!(w.router_inflight_load(), 0);
|
||||
|
||||
let w_inner = w.clone();
|
||||
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(move || {
|
||||
let _g = w_inner.load_guard();
|
||||
assert_eq!(w_inner.active_load(), 1);
|
||||
assert_eq!(w_inner.router_inflight_load(), 1);
|
||||
panic!("synthetic panic to exercise Drop on unwind");
|
||||
}));
|
||||
assert!(result.is_err(), "the closure must have panicked");
|
||||
assert_eq!(
|
||||
w.active_load(),
|
||||
w.router_inflight_load(),
|
||||
0,
|
||||
"LoadGuard's Drop must decrement even when the holder panics",
|
||||
);
|
||||
|
||||
@@ -740,7 +740,7 @@ async fn removed_awaits_pending_added() {
|
||||
/// independently — 2N round-trips for N workers.
|
||||
#[tokio::test]
|
||||
async fn manager_emits_single_server_info_fetch_per_worker() {
|
||||
use sgl_router::policies::kv_events::KvEventIndex;
|
||||
use sgl_router::state::kv_events::KvEventIndex;
|
||||
|
||||
let body = json!({
|
||||
"served_model_name": "m",
|
||||
|
||||
Reference in New Issue
Block a user