Skip to main content

s3_wire/
observer.rs

1//! Dependency-free, secret-safe request lifecycle observation.
2
3use std::time::Duration;
4
5use crate::{ErrorCategory, RetryClassification};
6
7/// Stage of one request attempt.
8#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9pub enum RequestEventKind {
10    /// A signed request attempt is about to be sent.
11    AttemptStarted,
12    /// An attempt completed successfully.
13    AttemptSucceeded,
14    /// An attempt failed and will not be retried.
15    AttemptFailed,
16    /// A retry was scheduled after an attempt failed.
17    RetryScheduled,
18    /// AWS supplied a validated region correction and the request will be re-signed.
19    RegionRedirected,
20}
21
22/// Sanitized lifecycle event for an S3 request attempt.
23///
24/// Object keys, bucket names, endpoints, headers, upload identifiers, service
25/// messages, and signing material are deliberately absent.
26#[derive(Clone, Copy, Debug, Eq, PartialEq)]
27pub struct RequestEvent<'a> {
28    /// Lifecycle stage.
29    pub kind: RequestEventKind,
30    /// HTTP method without its URL or headers.
31    pub method: &'a str,
32    /// One-based attempt number.
33    pub attempt: u32,
34    /// Stable error category, when this event follows a failure.
35    pub error_category: Option<ErrorCategory>,
36    /// Retry classification, when this event follows a failure.
37    pub retry_classification: Option<RetryClassification>,
38    /// Selected retry delay for `RetryScheduled`.
39    pub retry_delay: Option<Duration>,
40}
41
42/// Receives sanitized request lifecycle events.
43///
44/// Implementations must return quickly and must not block the async executor.
45/// Panics are isolated by the client and cannot fail an S3 operation.
46pub trait RequestObserver: Send + Sync {
47    /// Records one request lifecycle event.
48    fn on_event(&self, event: RequestEvent<'_>);
49}