Rootfix usage counter outbox

This commit is contained in:
fawney19
2026-05-19 00:30:24 +08:00
parent 19c8688eb1
commit 5eed329916
60 changed files with 4910 additions and 362 deletions

View File

@@ -108,6 +108,8 @@ fn api_format_matches(left: &str, right: &str) -> bool {
#[async_trait]
pub trait MinimalCandidateSelectionReadRepository: Send + Sync {
fn clear_local_cache(&self) {}
async fn list_for_exact_api_format(
&self,
api_format: &str,

View File

@@ -2,7 +2,8 @@ mod types;
pub use types::{
parse_usage_body_ref, usage_body_ref, usage_request_metadata_client_family,
PendingUsageCleanupSummary, ProviderApiKeyWindowUsageRequest, StoredProviderApiKeyUsageSummary,
ApiKeyLastUsedDelta, ManagementTokenCounterDelta, PendingUsageCleanupSummary,
ProviderApiKeyWindowUsageRequest, ProxyNodeCounterDelta, StoredProviderApiKeyUsageSummary,
StoredProviderApiKeyWindowUsageSummary, StoredProviderUsageSummary, StoredProviderUsageWindow,
StoredRequestUsageAudit, StoredUsageAuditAggregation, StoredUsageAuditSummary,
StoredUsageBreakdownSummaryRow, StoredUsageCacheAffinityHitSummary,
@@ -20,10 +21,11 @@ pub use types::{
UsageCacheAffinityHitSummaryQuery, UsageCacheAffinityIntervalGroupBy,
UsageCacheAffinityIntervalQuery, UsageCacheHitSummaryQuery, UsageCleanupExecutionMode,
UsageCleanupPreviewCounts, UsageCleanupSummary, UsageCleanupTargets, UsageCleanupWindow,
UsageCostSavingsSummaryQuery, UsageDailyHeatmapQuery, UsageDashboardDailyBreakdownQuery,
UsageDashboardProviderCountsQuery, UsageDashboardSummaryQuery, UsageErrorDistributionQuery,
UsageLeaderboardGroupBy, UsageLeaderboardQuery, UsageMonitoringErrorCountQuery,
UsageMonitoringErrorListQuery, UsagePerformancePercentilesQuery, UsageProviderPerformanceQuery,
UsageReadRepository, UsageRepository, UsageSettledCostSummaryQuery, UsageTimeSeriesGranularity,
UsageCostSavingsSummaryQuery, UsageCounterFlushSummary, UsageCounterHealthSnapshot,
UsageDailyHeatmapQuery, UsageDashboardDailyBreakdownQuery, UsageDashboardProviderCountsQuery,
UsageDashboardSummaryQuery, UsageErrorDistributionQuery, UsageLeaderboardGroupBy,
UsageLeaderboardQuery, UsageMonitoringErrorCountQuery, UsageMonitoringErrorListQuery,
UsagePerformancePercentilesQuery, UsageProviderPerformanceQuery, UsageReadRepository,
UsageRepository, UsageSettledCostSummaryQuery, UsageTimeSeriesGranularity,
UsageTimeSeriesQuery, UsageWriteRepository,
};

View File

@@ -1518,6 +1518,12 @@ pub trait UsageReadRepository: Send + Sync {
&self,
query: &UsageDailyHeatmapQuery,
) -> Result<Vec<StoredUsageDailySummary>, crate::DataLayerError>;
async fn read_usage_counter_health(
&self,
) -> Result<UsageCounterHealthSnapshot, crate::DataLayerError> {
Ok(UsageCounterHealthSnapshot::default())
}
}
/// Repository write model for a single usage aggregate.
@@ -1690,6 +1696,47 @@ pub trait UsageWriteRepository: Send + Sync {
Ok(PendingUsageCleanupSummary::default())
}
async fn flush_usage_counter_deltas(
&self,
batch_size: usize,
) -> Result<UsageCounterFlushSummary, crate::DataLayerError> {
let _ = batch_size;
Ok(UsageCounterFlushSummary::default())
}
async fn enqueue_proxy_node_counter_delta(
&self,
delta: ProxyNodeCounterDelta,
) -> Result<bool, crate::DataLayerError> {
let _ = delta;
Ok(false)
}
async fn enqueue_management_token_counter_delta(
&self,
delta: ManagementTokenCounterDelta,
) -> Result<bool, crate::DataLayerError> {
let _ = delta;
Ok(false)
}
async fn enqueue_api_key_last_used_delta(
&self,
delta: ApiKeyLastUsedDelta,
) -> Result<bool, crate::DataLayerError> {
let _ = delta;
Ok(false)
}
async fn cleanup_processed_usage_counter_deltas(
&self,
cutoff_unix_secs: u64,
batch_size: usize,
) -> Result<usize, crate::DataLayerError> {
let _ = (cutoff_unix_secs, batch_size);
Ok(0)
}
async fn cleanup_usage(
&self,
window: &UsageCleanupWindow,
@@ -1723,6 +1770,80 @@ pub struct PendingUsageCleanupSummary {
pub recovered: usize,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct UsageCounterFlushSummary {
pub rows_claimed: usize,
pub api_key_targets: usize,
pub provider_api_key_targets: usize,
pub model_targets: usize,
pub provider_monthly_targets: usize,
pub proxy_node_targets: usize,
pub management_token_targets: usize,
pub api_key_last_used_targets: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
pub struct UsageCounterHealthSnapshot {
pub pending_rows: u64,
pub processed_rows: u64,
pub oldest_pending_created_at_unix_secs: Option<u64>,
pub latest_processed_at_unix_secs: Option<u64>,
pub pending_by_kind: std::collections::BTreeMap<String, u64>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ProxyNodeCounterDelta {
pub node_id: String,
pub total_requests_delta: i64,
pub failed_requests_delta: i64,
pub dns_failures_delta: i64,
pub stream_errors_delta: i64,
}
impl ProxyNodeCounterDelta {
pub fn is_noop(&self) -> bool {
self.node_id.trim().is_empty()
|| (self.total_requests_delta <= 0
&& self.failed_requests_delta <= 0
&& self.dns_failures_delta <= 0
&& self.stream_errors_delta <= 0)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ManagementTokenCounterDelta {
pub token_id: String,
pub usage_count_delta: i64,
pub last_used_at_unix_secs: Option<u64>,
pub last_used_ip: Option<String>,
}
impl ManagementTokenCounterDelta {
pub fn is_noop(&self) -> bool {
self.token_id.trim().is_empty()
|| (self.usage_count_delta <= 0
&& self.last_used_at_unix_secs.is_none()
&& self
.last_used_ip
.as_deref()
.map(str::trim)
.unwrap_or("")
.is_empty())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ApiKeyLastUsedDelta {
pub api_key_id: String,
pub last_used_at_unix_secs: u64,
}
impl ApiKeyLastUsedDelta {
pub fn is_noop(&self) -> bool {
self.api_key_id.trim().is_empty()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
pub struct UsageCleanupSummary {
pub body_externalized: usize,