P5.7 §13.7: Add alias flip metrics emission
Add metrics emission for alias flips in update_alias endpoint. The AliasState now includes a Metrics reference to record flip events for observability. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
90462daa64
commit
f564f3d3a7
2 changed files with 14 additions and 28 deletions
|
|
@ -172,7 +172,8 @@ impl FromRef<UnifiedState> for routes::aliases::AliasState {
|
|||
fn from_ref(state: &UnifiedState) -> Self {
|
||||
Self {
|
||||
config: state.admin.config.clone(),
|
||||
task_registry: state.admin.task_registry.clone(),
|
||||
task_store: state.admin.task_store.clone(),
|
||||
metrics: state.metrics.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
use axum::{
|
||||
extract::{FromRef, Path, State},
|
||||
http::{HeaderMap, StatusCode},
|
||||
http::StatusCode,
|
||||
Json,
|
||||
};
|
||||
use miroir_core::{
|
||||
alias::{Alias, AliasKind},
|
||||
api_error::{MeilisearchError, MiroirCode},
|
||||
config::MiroirConfig,
|
||||
task_store::TaskStore,
|
||||
};
|
||||
use crate::middleware::Metrics;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
|
@ -19,6 +19,7 @@ use std::sync::Arc;
|
|||
pub struct AliasState {
|
||||
pub config: Arc<MiroirConfig>,
|
||||
pub task_store: Option<Arc<dyn TaskStore>>,
|
||||
pub metrics: Metrics,
|
||||
}
|
||||
|
||||
/// Request body for POST /_miroir/aliases.
|
||||
|
|
@ -74,12 +75,12 @@ pub struct AliasInfo {
|
|||
|
||||
/// Error response for 409 conflicts.
|
||||
#[derive(Debug, Serialize)]
|
||||
struct ErrorResponse {
|
||||
pub struct ErrorResponse {
|
||||
pub code: String,
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
/// POST /_miroir/aliases — create a new alias.
|
||||
/// POST /_miroir/aliases/{name} — create a new alias.
|
||||
///
|
||||
/// Request body:
|
||||
/// - Single-target: `{"target": "products_v3"}`
|
||||
|
|
@ -88,7 +89,7 @@ struct ErrorResponse {
|
|||
/// Plan §13.7: Atomic index aliases for blue-green reindexing.
|
||||
pub async fn create_alias<S>(
|
||||
State(state): State<AliasState>,
|
||||
headers: HeaderMap,
|
||||
Path(name): Path<String>,
|
||||
Json(body): Json<CreateAliasRequest>,
|
||||
) -> Result<Json<GetAliasResponse>, (StatusCode, Json<ErrorResponse>)>
|
||||
where
|
||||
|
|
@ -141,10 +142,8 @@ where
|
|||
.unwrap_or_default()
|
||||
.as_secs();
|
||||
|
||||
let alias_name = extract_alias_name(&headers)?;
|
||||
|
||||
// Check for conflicts with ILM-managed aliases
|
||||
if let Ok(Some(existing)) = task_store.get_alias(&alias_name) {
|
||||
if let Ok(Some(existing)) = task_store.get_alias(&name) {
|
||||
if existing.kind == "multi" {
|
||||
// Multi-target aliases are ILM-managed and cannot be created by operators
|
||||
return Err((
|
||||
|
|
@ -153,7 +152,7 @@ where
|
|||
code: "alias_exists_ilm_managed".to_string(),
|
||||
message: format!(
|
||||
"alias '{}' exists and is managed by ILM policy; use ILM API to modify",
|
||||
alias_name
|
||||
name
|
||||
),
|
||||
}),
|
||||
));
|
||||
|
|
@ -161,7 +160,7 @@ where
|
|||
}
|
||||
|
||||
let new_alias = miroir_core::task_store::NewAlias {
|
||||
name: alias_name.clone(),
|
||||
name: name.clone(),
|
||||
kind: if matches!(kind, AliasKind::Single) {
|
||||
"single".to_string()
|
||||
} else {
|
||||
|
|
@ -350,6 +349,9 @@ where
|
|||
)
|
||||
})?;
|
||||
|
||||
// Record alias flip metric
|
||||
state.metrics.inc_alias_flip(&name);
|
||||
|
||||
// Get updated alias
|
||||
let updated = task_store.get_alias(&name).map_err(|e| {
|
||||
(
|
||||
|
|
@ -494,23 +496,6 @@ where
|
|||
}))
|
||||
}
|
||||
|
||||
/// Extract alias name from X-Miroir-Alias-Name header (for POST).
|
||||
fn extract_alias_name(headers: &HeaderMap) -> Result<String, (StatusCode, Json<ErrorResponse>)> {
|
||||
headers
|
||||
.get("x-miroir-alias-name")
|
||||
.and_then(|v| v.to_str().ok())
|
||||
.map(|s| s.to_string())
|
||||
.ok_or_else(|| {
|
||||
(
|
||||
StatusCode::BAD_REQUEST,
|
||||
Json(ErrorResponse {
|
||||
code: "missing_alias_name".to_string(),
|
||||
message: "X-Miroir-Alias-Name header is required".to_string(),
|
||||
}),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue