retry_policy/policies/google_cloud_workflows/
http.rs1use retry_backoff::backoffs::google_cloud_workflows::Backoff;
2use retry_predicate::predicates::FnPredicate;
3
4use super::Policy;
5
6pub fn default_retry() -> Policy<Error> {
8 Policy::new(
9 FnPredicate::from(default_retry_predicate),
10 5,
11 Backoff::default(),
12 )
13}
14
15pub fn default_retry_non_idempotent() -> Policy<Error> {
17 Policy::new(
18 FnPredicate::from(default_retry_predicate_non_idempotent),
19 5,
20 Backoff::default(),
21 )
22}
23
24pub fn default_retry_predicate(err: &Error) -> bool {
26 matches!(
27 err,
28 Error::TooManyRequests {
29 retry_after_delay_seconds: _
30 } | &Error::BadGateway
31 | Error::ServiceUnavailable {
32 retry_after_delay_seconds: _
33 }
34 | &Error::GatewayTimeout
35 | Error::ConnectionError
36 | Error::TimeoutError
37 )
38}
39
40pub fn default_retry_predicate_non_idempotent(err: &Error) -> bool {
42 matches!(
43 err,
44 Error::TooManyRequests {
45 retry_after_delay_seconds: _
46 } | Error::ServiceUnavailable {
47 retry_after_delay_seconds: _
48 }
49 )
50}
51
52#[derive(Debug)]
54pub enum Error {
55 TooManyRequests {
57 retry_after_delay_seconds: Option<usize>,
59 },
60 BadGateway,
62 ServiceUnavailable {
64 retry_after_delay_seconds: Option<usize>,
66 },
67 GatewayTimeout,
69 ConnectionError,
70 TimeoutError,
71 Other,
72}
73
74impl core::fmt::Display for Error {
75 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
76 write!(f, "{self:?}")
77 }
78}
79
80impl core::error::Error for Error {}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn test_default_retry() {
88 let policy = default_retry();
89 for err in &[
90 Error::TooManyRequests {
91 retry_after_delay_seconds: None,
92 },
93 Error::BadGateway,
94 Error::ServiceUnavailable {
95 retry_after_delay_seconds: None,
96 },
97 Error::GatewayTimeout,
98 Error::ConnectionError,
99 Error::TimeoutError,
100 ] {
101 assert!(policy.predicate.test(err));
102 }
103 #[allow(clippy::single_element_loop)]
104 for err in &[Error::Other] {
105 assert!(!policy.predicate.test(err));
106 }
107 assert_eq!(policy.max_retries, 5);
108 assert_eq!(policy.backoff, Backoff::default());
109 }
110
111 #[test]
112 fn test_default_retry_non_idempotent() {
113 let policy = default_retry_non_idempotent();
114 for err in &[
115 Error::TooManyRequests {
116 retry_after_delay_seconds: None,
117 },
118 Error::ServiceUnavailable {
119 retry_after_delay_seconds: None,
120 },
121 ] {
122 assert!(policy.predicate.test(err));
123 }
124 for err in &[
125 Error::BadGateway,
126 Error::GatewayTimeout,
127 Error::ConnectionError,
128 Error::TimeoutError,
129 Error::Other,
130 ] {
131 assert!(!policy.predicate.test(err));
132 }
133 assert_eq!(policy.max_retries, 5);
134 assert_eq!(policy.backoff, Backoff::default());
135 }
136
137 #[cfg(feature = "alloc")]
138 #[test]
139 fn test_error_display() {
140 assert_eq!(alloc::format!("{}", Error::BadGateway), "BadGateway")
141 }
142}