fix: harden concurrency limits and high-RPM runtime paths

Bound request, stream, queue, and shutdown resource lifetimes. Reduce scheduler and Redis hot-path work and isolate database maintenance. Include regression coverage, load probes, and concurrency audit results.
This commit is contained in:
elky
2026-09-10 08:14:58 +08:00
parent 361952ada9
commit ecc16673eb
149 changed files with 27963 additions and 1926 deletions
@@ -0,0 +1,366 @@
use super::*;
fn config() -> UsageRuntimeConfig {
UsageRuntimeConfig {
enabled: true,
queue_terminal_events: true,
queue_lifecycle_events: true,
worker_count: 2,
consumer_block_ms: 60_000,
enqueue_retry_buffer_capacity: 256,
enqueue_retry_initial_backoff_ms: 60_000,
enqueue_retry_max_backoff_ms: 60_000,
..UsageRuntimeConfig::default()
}
}
fn store() -> CloneQueueConfiguredUsageStore {
CloneQueueConfiguredUsageStore {
records: Arc::new(Mutex::new(Vec::new())),
queue: Arc::new(RuntimeState::memory(MemoryRuntimeStateConfig::default())),
}
}
fn terminal(request_id: &str) -> UsageEvent {
UsageEvent::new(
UsageEventType::Completed,
request_id,
UsageEventData {
provider_name: "openai".to_string(),
model: "test".to_string(),
status_code: Some(200),
input_tokens: Some(3),
output_tokens: Some(7),
total_tokens: Some(10),
..UsageEventData::default()
},
)
}
#[tokio::test]
async fn usage_shutdown_waits_for_a_producer_before_closing_admission() {
let runtime = UsageRuntime::new(config()).unwrap();
let store = store();
let producer = runtime.track_producer();
let copy = runtime.clone();
let task = tokio::spawn(async move { copy.shutdown(Duration::from_secs(3)).await });
sleep(Duration::from_millis(30)).await;
assert!(!task.is_finished());
runtime
.submit_terminal_event(&store, terminal("last-producer"))
.await;
drop(producer);
task.await.unwrap().unwrap();
assert_eq!(runtime.local_work_pending(), 0);
assert_eq!(
store
.queue
.stats(&runtime.config.stream_key, None)
.await
.unwrap()
.stream_length,
1
);
runtime.shutdown(Duration::from_secs(1)).await.unwrap();
runtime
.submit_terminal_event(&store, terminal("closed"))
.await;
runtime
.record_terminal_event(&store, terminal("closed-direct-api"))
.await;
assert_eq!(
store
.queue
.stats(&runtime.config.stream_key, None)
.await
.unwrap()
.stream_length,
1
);
}
#[tokio::test]
async fn usage_shutdown_persists_concurrent_terminal_handoffs() {
let runtime = UsageRuntime::new(config()).unwrap();
let store = store();
let mut tasks = tokio::task::JoinSet::new();
for index in 0..128 {
let runtime = runtime.clone();
let store = store.clone();
let producer = runtime.track_producer();
tasks.spawn(async move {
let _producer = producer;
runtime
.submit_terminal_event(&store, terminal(&format!("drain-{index}")))
.await;
});
}
runtime.shutdown(Duration::from_secs(5)).await.unwrap();
while let Some(result) = tasks.join_next().await {
result.unwrap();
}
assert_eq!(
store
.queue
.stats(&runtime.config.stream_key, None)
.await
.unwrap()
.stream_length,
128
);
assert_eq!(runtime.local_work_pending(), 0);
}
#[tokio::test]
async fn usage_shutdown_wakes_retry_backoff_and_preserves_all_buffered_events() {
let runtime = UsageRuntime::new(config()).unwrap();
let store = store();
let queue = UsageQueue::new(Arc::clone(&store.queue), runtime.config.clone()).unwrap();
for index in 0..32 {
assert!(runtime.enqueue_retry.schedule(
queue.clone(),
terminal(&format!("retry-{index}")),
"terminal",
DataLayerError::Redis("transient".into())
));
}
runtime.shutdown(Duration::from_secs(3)).await.unwrap();
assert_eq!(runtime.enqueue_retry.pending(), 0);
assert_eq!(runtime.enqueue_retry.recovered_total(), 32);
assert_eq!(
store
.queue
.stats(&runtime.config.stream_key, None)
.await
.unwrap()
.stream_length,
32
);
}
#[tokio::test]
async fn usage_shutdown_failure_retains_retry_work_for_a_later_attempt() {
let runtime = UsageRuntime::new(config()).unwrap();
let store = store();
let flaky = Arc::new(FlakyAppendQueueStore::new(
Arc::clone(&store.queue),
usize::MAX,
));
let queue = UsageQueue::new(flaky.clone(), runtime.config.clone()).unwrap();
assert!(runtime.enqueue_retry.schedule(
queue,
terminal("recover-after-deadline"),
"terminal",
DataLayerError::Redis("unavailable".into())
));
let result = runtime.shutdown(Duration::from_millis(150)).await;
assert!(matches!(result, Err(DataLayerError::TimedOut(_))));
assert_eq!(runtime.enqueue_retry.pending(), 1);
assert!(flaky.append_attempts.load(Ordering::Acquire) <= 4);
flaky.remaining_failures.store(0, Ordering::Release);
runtime.shutdown(Duration::from_secs(3)).await.unwrap();
assert_eq!(runtime.enqueue_retry.recovered_total(), 1);
assert_eq!(
store
.queue
.stats(&runtime.config.stream_key, None)
.await
.unwrap()
.stream_length,
1
);
}
#[tokio::test]
async fn usage_shutdown_flushes_delayed_lifecycle_without_waiting_for_its_timer() {
let mut config = config();
config.lifecycle_enqueue_delay_ms = 60_000;
let runtime = UsageRuntime::new(config).unwrap();
let store = store();
let event = UsageEvent::new(
UsageEventType::Pending,
"delayed",
UsageEventData::default(),
);
runtime
.enqueue_lifecycle_event_with_config_delay(&store, event)
.await;
assert!(runtime.local_work_pending() > 0);
runtime.shutdown(Duration::from_secs(3)).await.unwrap();
assert_eq!(runtime.local_work_pending(), 0);
assert_eq!(
store
.queue
.stats(&runtime.config.stream_key, None)
.await
.unwrap()
.stream_length,
1
);
}
#[tokio::test]
async fn usage_shutdown_stops_every_idle_worker_and_supervisor() {
for supervised in [false, true] {
let runtime = UsageRuntime::new(config()).unwrap();
let store = Arc::new(store());
let handles = if supervised {
vec![runtime.spawn_worker_supervisor(store).unwrap()]
} else {
runtime.spawn_workers(store)
};
sleep(Duration::from_millis(30)).await;
runtime.shutdown(Duration::from_secs(3)).await.unwrap();
for handle in handles {
timeout(Duration::from_secs(1), handle)
.await
.unwrap()
.unwrap();
}
assert_eq!(runtime.metrics_snapshot().worker_active_count, 0);
assert_eq!(runtime.shutdown.supervisors.load(Ordering::Acquire), 0);
}
}
#[tokio::test]
async fn usage_shutdown_does_not_cancel_a_write_or_ack_its_unfinished_record() {
let runtime = UsageRuntime::new(config()).unwrap();
let store = BlockingWriteQueueConfiguredUsageStore {
records: Arc::new(Mutex::new(Vec::new())),
queue: store().queue,
write_started: Arc::new(tokio::sync::Notify::new()),
release_writes: Arc::new(tokio::sync::Notify::new()),
writes_completed: Arc::new(AtomicUsize::new(0)),
};
let queue = UsageQueue::new(Arc::clone(&store.queue), runtime.config.clone()).unwrap();
queue.ensure_consumer_group().await.unwrap();
queue.enqueue(&terminal("in-flight-worker")).await.unwrap();
let worker = runtime.spawn_worker(Arc::new(store.clone())).unwrap();
timeout(Duration::from_secs(3), store.write_started.notified())
.await
.unwrap();
assert!(runtime.shutdown(Duration::from_millis(50)).await.is_err());
assert!(!worker.is_finished());
assert_eq!(
store
.queue
.stats(
&runtime.config.stream_key,
Some(&runtime.config.consumer_group)
)
.await
.unwrap()
.group_pending,
1
);
store.release_writes.notify_one();
runtime.shutdown(Duration::from_secs(3)).await.unwrap();
worker.await.unwrap();
assert_eq!(store.writes_completed.load(Ordering::Acquire), 1);
assert_eq!(
store
.queue
.stats(
&runtime.config.stream_key,
Some(&runtime.config.consumer_group)
)
.await
.unwrap()
.group_pending,
0
);
}
#[tokio::test]
async fn usage_shutdown_disabled_runtime_is_immediate() {
UsageRuntime::disabled()
.shutdown(Duration::from_secs(1))
.await
.unwrap();
}
#[tokio::test]
async fn usage_shutdown_consumes_process_local_queue_before_stopping_workers() {
let runtime = UsageRuntime::new(config()).unwrap();
let store = store();
let worker = runtime
.spawn_worker_supervisor(Arc::new(store.clone()))
.unwrap();
for index in 0..64 {
runtime
.submit_terminal_event(&store, terminal(&format!("local-{index}")))
.await;
}
runtime
.shutdown_with_local_queue(Duration::from_secs(5), Some(Arc::clone(&store.queue)))
.await
.unwrap();
worker.await.unwrap();
assert_eq!(store.records.lock().unwrap().len(), 64);
assert_eq!(
store
.queue
.stats(
&runtime.config.stream_key,
Some(&runtime.config.consumer_group)
)
.await
.unwrap()
.group_pending,
0
);
}
#[tokio::test]
async fn usage_shutdown_rejects_unconsumed_memory_queue_as_success() {
let runtime = UsageRuntime::new(config()).unwrap();
let store = store();
runtime
.submit_terminal_event(&store, terminal("unconsumed"))
.await;
let result = runtime
.shutdown_with_local_queue(Duration::from_millis(50), Some(Arc::clone(&store.queue)))
.await;
assert!(result.is_err());
let worker = runtime.spawn_worker(Arc::new(store.clone())).unwrap();
runtime
.shutdown_with_local_queue(Duration::from_secs(3), Some(Arc::clone(&store.queue)))
.await
.unwrap();
worker.await.unwrap();
assert_eq!(store.records.lock().unwrap().len(), 1);
}
#[tokio::test]
async fn usage_shutdown_does_not_miss_accepted_pending_to_terminal_handoffs() {
let mut config = config();
config.queue_terminal_events = false;
let runtime = UsageRuntime::new(config).unwrap();
let store = store();
for index in 0..32 {
let id = format!("ordered-{index}");
let plan = terminal_test_plan(&id);
runtime.record_pending(&store, build_lifecycle_usage_seed(&plan, None));
runtime.record_stream_started(
&store,
&build_lifecycle_usage_seed(&plan, None),
200,
Some(&ExecutionTelemetry {
ttfb_ms: Some(5),
elapsed_ms: None,
upstream_bytes: None,
}),
);
runtime.submit_terminal_event(&store, terminal(&id)).await;
}
runtime.shutdown(Duration::from_secs(5)).await.unwrap();
let records = store.records.lock().unwrap();
for index in 0..32 {
let statuses: Vec<_> = records
.iter()
.filter(|r| r.request_id == format!("ordered-{index}"))
.map(|r| r.status.as_str())
.collect();
assert_eq!(statuses, ["pending", "streaming", "completed"]);
}
}