From 424f2fec34b3500c9eaa2509be857fbe516efc04 Mon Sep 17 00:00:00 2001 From: npub1tquskdu6yc4h8l7xxtceculxw600grekeq0xg2ukqfrwl7vrzg3quz3gmp <58390b379a262b73ffc632f19c73e6769ef40f36c81e642b960246eff9831222@buzz.block.builderlab.xyz> Date: Thu, 30 Jul 2026 17:17:35 -0700 Subject: [PATCH] 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> --- crates/buzz-push-gateway/src/apns.rs | 18 ------------------ crates/buzz-push-gateway/src/http.rs | 15 +++++---------- crates/buzz-push-gateway/src/metrics.rs | 13 ++----------- docs/push-gateway-deployment.md | 5 ++--- 4 files changed, 9 insertions(+), 42 deletions(-) diff --git a/crates/buzz-push-gateway/src/apns.rs b/crates/buzz-push-gateway/src/apns.rs index ea79b779f..63142390c 100644 --- a/crates/buzz-push-gateway/src/apns.rs +++ b/crates/buzz-push-gateway/src/apns.rs @@ -24,8 +24,6 @@ pub enum DeliveryOutcome { /// Retry-After delay in seconds, clamped by the transport. retry_after_seconds: Option, }, - /// 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!( diff --git a/crates/buzz-push-gateway/src/http.rs b/crates/buzz-push-gateway/src/http.rs index 0564972c0..e9980d7ca 100644 --- a/crates/buzz-push-gateway/src/http.rs +++ b/crates/buzz-push-gateway/src/http.rs @@ -656,17 +656,12 @@ async fn deliver(State(s): State, 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, 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"), diff --git a/crates/buzz-push-gateway/src/metrics.rs b/crates/buzz-push-gateway/src/metrics.rs index f40c126c7..13ce63f81 100644 --- a/crates/buzz-push-gateway/src/metrics.rs +++ b/crates/buzz-push-gateway/src/metrics.rs @@ -41,13 +41,12 @@ pub fn install() -> Result { /// 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", diff --git a/docs/push-gateway-deployment.md b/docs/push-gateway-deployment.md index 64c10dd79..9ca28b851 100644 --- a/docs/push-gateway-deployment.md +++ b/docs/push-gateway-deployment.md @@ -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. |