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:
npub1tquskdu6yc4h8l7xxtceculxw600grekeq0xg2ukqfrwl7vrzg3quz3gmp
2026-07-30 17:17:35 -07:00
parent 80001b6eae
commit 424f2fec34
4 changed files with 9 additions and 42 deletions
-18
View File
@@ -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!(
+5 -10
View File
@@ -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"),
+2 -11
View File
@@ -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",
+2 -3
View File
@@ -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. |