mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
- 新增 aether-ai-pipeline 和 aether-data-contracts crate,将 pipeline 逻辑与数据契约从 gateway 中解耦 - 重构 admin handlers:拆分单体模块为 auth/billing/endpoint/features/model/observability/provider/system 等独立子模块 - 合并 chat/cli 重复代码路径:精简 conversion、finalize、planner 中的 sync/chat/cli 分支 - 重构 scheduler/executor/data 层,引入 facade 模式降低模块间耦合 - 移除冗余的 intent 模块,将 plan_fallback/policy/stream_path/sync_path 迁移至 executor - 前端适配:调整 admin API 调用和 provider 模型测试对话框
113 lines
3.4 KiB
Rust
113 lines
3.4 KiB
Rust
use aether_data_contracts::DataLayerError;
|
|
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct UsageRuntimeConfig {
|
|
pub enabled: bool,
|
|
pub stream_key: String,
|
|
pub consumer_group: String,
|
|
pub dlq_stream_key: String,
|
|
pub stream_maxlen: usize,
|
|
pub consumer_batch_size: usize,
|
|
pub consumer_block_ms: u64,
|
|
pub reclaim_idle_ms: u64,
|
|
pub reclaim_count: usize,
|
|
pub reclaim_interval_ms: u64,
|
|
}
|
|
|
|
impl Default for UsageRuntimeConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
enabled: false,
|
|
stream_key: "usage:events".to_string(),
|
|
consumer_group: "usage_consumers".to_string(),
|
|
dlq_stream_key: "usage:events:dlq".to_string(),
|
|
stream_maxlen: 2_000,
|
|
consumer_batch_size: 200,
|
|
consumer_block_ms: 500,
|
|
reclaim_idle_ms: 30_000,
|
|
reclaim_count: 200,
|
|
reclaim_interval_ms: 5_000,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl UsageRuntimeConfig {
|
|
pub fn disabled() -> Self {
|
|
Self::default()
|
|
}
|
|
|
|
pub fn validate(&self) -> Result<(), DataLayerError> {
|
|
if !self.enabled {
|
|
return Ok(());
|
|
}
|
|
|
|
if self.stream_key.trim().is_empty() {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime stream_key cannot be empty".to_string(),
|
|
));
|
|
}
|
|
if self.consumer_group.trim().is_empty() {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime consumer_group cannot be empty".to_string(),
|
|
));
|
|
}
|
|
if self.dlq_stream_key.trim().is_empty() {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime dlq_stream_key cannot be empty".to_string(),
|
|
));
|
|
}
|
|
if self.stream_maxlen == 0 {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime stream_maxlen must be positive".to_string(),
|
|
));
|
|
}
|
|
if self.consumer_batch_size == 0 {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime consumer_batch_size must be positive".to_string(),
|
|
));
|
|
}
|
|
if self.consumer_block_ms == 0 {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime consumer_block_ms must be positive".to_string(),
|
|
));
|
|
}
|
|
if self.reclaim_idle_ms == 0 {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime reclaim_idle_ms must be positive".to_string(),
|
|
));
|
|
}
|
|
if self.reclaim_count == 0 {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime reclaim_count must be positive".to_string(),
|
|
));
|
|
}
|
|
if self.reclaim_interval_ms == 0 {
|
|
return Err(DataLayerError::InvalidConfiguration(
|
|
"usage runtime reclaim_interval_ms must be positive".to_string(),
|
|
));
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::UsageRuntimeConfig;
|
|
|
|
#[test]
|
|
fn disabled_config_is_valid() {
|
|
assert!(UsageRuntimeConfig::disabled().validate().is_ok());
|
|
}
|
|
|
|
#[test]
|
|
fn enabled_config_rejects_empty_stream_key() {
|
|
let config = UsageRuntimeConfig {
|
|
enabled: true,
|
|
stream_key: String::new(),
|
|
..UsageRuntimeConfig::default()
|
|
};
|
|
assert!(config.validate().is_err());
|
|
}
|
|
}
|