This commit is contained in:
Mateusz Gruszczyński committed 2026-10-10 20:56:36 +02:00
1 parent f213d853e2
commit 76b8bb7ee2
78 files changed
+7750 -5204

No files matched your search

+25 -9
View File
@@ -79,6 +79,8 @@ async fn cache_purge(
));
}
}
let permit = state.cache_invalidation_slots.clone().try_acquire_owned()
.map_err(|_| ApiError(StatusCode::TOO_MANY_REQUESTS, "cache maintenance busy".into()))?;
let detail = format!(
"scope={}; in-flight fills invalidated",
scope.vhost.as_deref().unwrap_or("all")
@@ -88,10 +90,15 @@ async fn cache_purge(
.audit(&session.username, "cache.purge", &detail)
.await
.map_err(auth::internal)?;
let purged = match &scope.vhost {
Some(id) => state.cache.purge_scope(id),
None => state.cache.purge(None),
};
let cache = state.cache.clone();
let vhost = scope.vhost.clone();
let purged = tokio::task::spawn_blocking(move || {
let _permit = permit;
match &vhost {
Some(id) => cache.purge_scope(id),
None => cache.purge(None),
}
}).await.map_err(auth::internal)?;
Ok(Json(
json!({"purged_entries":purged, "vhost":scope.vhost, "metrics":state.cache.view()}),
))
@@ -119,6 +126,8 @@ async fn cache_invalidate(
));
}
}
let permit = state.cache_invalidation_slots.clone().try_acquire_owned()
.map_err(|_| ApiError(StatusCode::TOO_MANY_REQUESTS, "cache maintenance busy".into()))?;
let detail = format!(
"operation={:?}; selector={:?}; vhost={}; host={}; value={:?}",
request.operation,
@@ -132,10 +141,12 @@ async fn cache_invalidate(
.audit(&session.username, "cache.invalidate", &detail)
.await
.map_err(auth::internal)?;
let result = state
.cache
.invalidate(request)
.map_err(|error| ApiError(StatusCode::UNPROCESSABLE_ENTITY, error.to_string()))?;
let cache = state.cache.clone();
let result = tokio::task::spawn_blocking(move || {
let _permit = permit;
cache.invalidate(request)
}).await.map_err(auth::internal)?
.map_err(|error| ApiError(StatusCode::UNPROCESSABLE_ENTITY, error.to_string()))?;
Ok(Json(json!({
"result": result,
"metrics": state.cache.view(),
@@ -152,7 +163,9 @@ async fn cache_ban_delete(
Extension(session): Extension<Session>,
Path(id): Path<u64>,
) -> Result<Json<Value>, ApiError> {
if !state.cache.remove_ban(id) {
// This is a destructive operation: fail closed if the audit store is
// unavailable, rather than removing a ban and only then trying to log it.
if !state.cache.bans().iter().any(|rule| rule.id == id) {
return Err(ApiError(
StatusCode::NOT_FOUND,
"unknown cache BAN rule".into(),
@@ -167,6 +180,9 @@ async fn cache_ban_delete(
)
.await
.map_err(auth::internal)?;
if !state.cache.remove_ban(id) {
return Err(ApiError(StatusCode::NOT_FOUND, "unknown cache BAN rule".into()));
}
Ok(Json(json!({"removed": id, "bans": state.cache.bans()})))
}