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}