mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
refactor(push): remove dead credential refresh path
Co-authored-by: npub1tquskdu6yc4h8l7xxtceculxw600grekeq0xg2ukqfrwl7vrzg3quz3gmp <58390b379a262b73ffc632f19c73e6769ef40f36c81e642b960246eff9831222@buzz.block.builderlab.xyz> Signed-off-by: npub1tquskdu6yc4h8l7xxtceculxw600grekeq0xg2ukqfrwl7vrzg3quz3gmp <58390b379a262b73ffc632f19c73e6769ef40f36c81e642b960246eff9831222@buzz.block.builderlab.xyz>
This commit is contained in:
parent
80001b6eae
commit
424f2fec34
@@ -24,8 +24,6 @@ pub enum DeliveryOutcome {
|
||||
/// Retry-After delay in seconds, clamped by the transport.
|
||||
retry_after_seconds: Option<i64>,
|
||||
},
|
||||
/// Refresh a transport credential, then retry once within normal attempt bounds.
|
||||
RefreshCredential,
|
||||
/// Provider credential/profile configuration is unhealthy; do not invalidate endpoints.
|
||||
ConfigurationFault,
|
||||
/// The locally-generated request is permanently invalid.
|
||||
@@ -82,8 +80,6 @@ pub trait PushTransport: Send + Sync {
|
||||
profile: AppProfile,
|
||||
endpoint: &str,
|
||||
) -> DeliveryOutcome;
|
||||
/// Refresh a transport credential after a refreshable provider outcome.
|
||||
fn refresh_credential(&self);
|
||||
}
|
||||
|
||||
/// Direct HTTP/2 APNs transport using a client certificate identity.
|
||||
@@ -219,10 +215,6 @@ impl PushTransport for ApnsTransport {
|
||||
outcome => outcome,
|
||||
}
|
||||
}
|
||||
|
||||
fn refresh_credential(&self) {
|
||||
panic!("certificate-authenticated APNs transport has no refreshable credential")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -395,16 +387,6 @@ mod tests {
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "certificate-authenticated APNs transport has no refreshable credential"
|
||||
)]
|
||||
fn certificate_transport_fails_loudly_if_refresh_is_requested() {
|
||||
let transport =
|
||||
ApnsTransport::certificate(TEST_IDENTITY_PEM, "app.topic".to_owned()).unwrap();
|
||||
transport.refresh_credential();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_classes_do_not_massacre_endpoints_on_provider_faults() {
|
||||
assert_eq!(
|
||||
|
||||
@@ -656,17 +656,12 @@ async fn deliver(State(s): State<AppState>, headers: HeaderMap, body: Bytes) ->
|
||||
// fence. The detached task completes disposition bookkeeping.
|
||||
let delivery = tokio::spawn(async move {
|
||||
let started = std::time::Instant::now();
|
||||
let mut outcome = transport.send(attempt, profile, &endpoint).await;
|
||||
if outcome == DeliveryOutcome::RefreshCredential {
|
||||
crate::metrics::record_credential_refresh();
|
||||
transport.refresh_credential();
|
||||
outcome = transport.send(attempt, profile, &endpoint).await;
|
||||
}
|
||||
let outcome = transport.send(attempt, profile, &endpoint).await;
|
||||
crate::metrics::record_apns_delivery(outcome, started.elapsed().as_secs_f64());
|
||||
let disposition = match outcome {
|
||||
DeliveryOutcome::Retry { .. }
|
||||
| DeliveryOutcome::ConfigurationFault
|
||||
| DeliveryOutcome::RefreshCredential => DeliveryDisposition::Retryable,
|
||||
DeliveryOutcome::Retry { .. } | DeliveryOutcome::ConfigurationFault => {
|
||||
DeliveryDisposition::Retryable
|
||||
}
|
||||
DeliveryOutcome::Accepted
|
||||
| DeliveryOutcome::InvalidEndpoint { .. }
|
||||
| DeliveryOutcome::PermanentRequestFault => DeliveryDisposition::Terminal,
|
||||
@@ -704,7 +699,7 @@ async fn deliver(State(s): State<AppState>, headers: HeaderMap, body: Bytes) ->
|
||||
}),
|
||||
)
|
||||
.into_response(),
|
||||
DeliveryOutcome::ConfigurationFault | DeliveryOutcome::RefreshCredential => {
|
||||
DeliveryOutcome::ConfigurationFault => {
|
||||
error(StatusCode::SERVICE_UNAVAILABLE, "configuration_fault")
|
||||
}
|
||||
DeliveryOutcome::PermanentRequestFault => error(StatusCode::BAD_REQUEST, "invalid_request"),
|
||||
|
||||
@@ -41,13 +41,12 @@ pub fn install() -> Result<PrometheusHandle, BuildError> {
|
||||
|
||||
/// Stable metric label for each sanitized delivery outcome. The mapping is total
|
||||
/// over the closed [`DeliveryOutcome`] enum, so the `outcome` label can only take
|
||||
/// these six values.
|
||||
/// these five values.
|
||||
fn outcome_label(outcome: DeliveryOutcome) -> &'static str {
|
||||
match outcome {
|
||||
DeliveryOutcome::Accepted => "accepted",
|
||||
DeliveryOutcome::InvalidEndpoint { .. } => "invalid_endpoint",
|
||||
DeliveryOutcome::Retry { .. } => "retry",
|
||||
DeliveryOutcome::RefreshCredential => "refresh_credential",
|
||||
DeliveryOutcome::ConfigurationFault => "configuration_fault",
|
||||
DeliveryOutcome::PermanentRequestFault => "permanent_request_fault",
|
||||
}
|
||||
@@ -60,11 +59,6 @@ pub fn record_apns_delivery(outcome: DeliveryOutcome, seconds: f64) {
|
||||
metrics::histogram!("push_gateway_apns_delivery_seconds").record(seconds);
|
||||
}
|
||||
|
||||
/// Record that a cached provider credential was refreshed after APNs reported expiry.
|
||||
pub fn record_credential_refresh() {
|
||||
metrics::counter!("push_gateway_apns_credential_refreshes_total").increment(1);
|
||||
}
|
||||
|
||||
/// Delivery-admission result at the `authorize_delivery` seam.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Admission {
|
||||
@@ -126,7 +120,7 @@ mod tests {
|
||||
#[test]
|
||||
fn outcome_label_covers_every_variant_with_static_strings() {
|
||||
// Exhaustive over the closed enum; each arm is a compile-time constant,
|
||||
// so the `outcome` label is structurally bounded to these six values.
|
||||
// so the `outcome` label is structurally bounded to these five values.
|
||||
for (outcome, expected) in [
|
||||
(DeliveryOutcome::Accepted, "accepted"),
|
||||
(
|
||||
@@ -141,7 +135,6 @@ mod tests {
|
||||
},
|
||||
"retry",
|
||||
),
|
||||
(DeliveryOutcome::RefreshCredential, "refresh_credential"),
|
||||
(DeliveryOutcome::ConfigurationFault, "configuration_fault"),
|
||||
(
|
||||
DeliveryOutcome::PermanentRequestFault,
|
||||
@@ -166,7 +159,6 @@ mod tests {
|
||||
},
|
||||
0.030,
|
||||
);
|
||||
record_credential_refresh();
|
||||
record_admission(Admission::Admitted);
|
||||
record_admission(Admission::Rejected);
|
||||
record_admission(Admission::Unavailable);
|
||||
@@ -182,7 +174,6 @@ mod tests {
|
||||
for needle in [
|
||||
"push_gateway_apns_deliveries_total",
|
||||
"push_gateway_apns_delivery_seconds",
|
||||
"push_gateway_apns_credential_refreshes_total",
|
||||
"push_gateway_admissions_total",
|
||||
"push_gateway_delivery_errors_total",
|
||||
"push_gateway_reaper_failures_total",
|
||||
|
||||
@@ -42,13 +42,12 @@ The service reaps expired challenges and replay rows, idle quota rows, expired/r
|
||||
|
||||
## Metrics and alerting
|
||||
|
||||
The gateway serves Prometheus metrics at `GET /metrics` on the **private health listener** (`BUZZ_PUSH_HEALTH_ADDR`, default `0.0.0.0:8081`) — the same port as the probes, never on the public `8080`. All series are sanitized and bounded-cardinality: label values are drawn only from closed sets (the six APNs outcome classes, the fixed admission results, the static error codes already returned to callers, and the readiness causes). No endpoint, device token, relay pubkey, request id, or any request-scoped identifier is ever used as a label.
|
||||
The gateway serves Prometheus metrics at `GET /metrics` on the **private health listener** (`BUZZ_PUSH_HEALTH_ADDR`, default `0.0.0.0:8081`) — the same port as the probes, never on the public `8080`. All series are sanitized and bounded-cardinality: label values are drawn only from closed sets (the five APNs outcome classes, the fixed admission results, the static error codes already returned to callers, and the readiness causes). No endpoint, device token, relay pubkey, request id, or any request-scoped identifier is ever used as a label.
|
||||
|
||||
| Metric | Type | Labels | Meaning |
|
||||
|---|---|---|---|
|
||||
| `push_gateway_apns_deliveries_total` | counter | `outcome` = `accepted` \| `invalid_endpoint` \| `retry` \| `refresh_credential` \| `configuration_fault` \| `permanent_request_fault` | Terminal APNs send outcomes. |
|
||||
| `push_gateway_apns_deliveries_total` | counter | `outcome` = `accepted` \| `invalid_endpoint` \| `retry` \| `configuration_fault` \| `permanent_request_fault` | Terminal APNs send outcomes. |
|
||||
| `push_gateway_apns_delivery_seconds` | histogram | — | APNs send round-trip latency (seconds). |
|
||||
| `push_gateway_apns_credential_refreshes_total` | counter | — | Transport credential refreshes requested after a refreshable provider outcome. |
|
||||
| `push_gateway_admissions_total` | counter | `result` = `admitted` \| `rejected` \| `unavailable` | Outcome at the `authorize_delivery` replay/quota fence. |
|
||||
| `push_gateway_delivery_errors_total` | counter | `class` (static) | Selected delivery-handler exit classes only (see note). |
|
||||
| `push_gateway_reaper_failures_total` | counter | — | Retention reaper sweep failures. |
|
||||
|
||||
Reference in New Issue
Block a user