google_cloud_storage/storage/
request_options.rs1use super::common_options::CommonOptions;
16use crate::{
17 read_resume_policy::ReadResumePolicy,
18 storage::checksum::details::{Checksum, Crc32c},
19};
20use gaxi::options::ClientConfig;
21use google_cloud_gax::{
22 backoff_policy::BackoffPolicy,
23 retry_policy::RetryPolicy,
24 retry_throttler::{AdaptiveThrottler, SharedRetryThrottler},
25};
26use std::sync::{Arc, Mutex};
27use std::time::Duration;
28
29const DEFAULT_BIDI_ATTEMPT_TIMEOUT: Duration = Duration::from_secs(60);
31
32#[derive(Clone, Debug)]
37pub struct RequestOptions {
38 pub(crate) retry_policy: Arc<dyn RetryPolicy>,
39 pub(crate) backoff_policy: Arc<dyn BackoffPolicy>,
40 pub(crate) retry_throttler: SharedRetryThrottler,
41 pub(crate) idempotency: Option<bool>,
42 pub(crate) checksum: Checksum,
43 pub(crate) automatic_decompression: bool,
44 pub(crate) common_options: CommonOptions,
45 pub(crate) bidi_attempt_timeout: Duration,
46 pub(crate) user_agent: Option<String>,
47}
48
49impl RequestOptions {
50 pub(crate) fn new() -> Self {
51 let retry_policy = Arc::new(crate::retry_policy::storage_default());
52 let backoff_policy = Arc::new(crate::backoff_policy::default());
53 let retry_throttler = Arc::new(Mutex::new(AdaptiveThrottler::default()));
54 Self::new_with_policies(
55 retry_policy,
56 backoff_policy,
57 retry_throttler,
58 CommonOptions::new(),
59 )
60 }
61
62 pub(crate) fn new_with_client_config(
63 config: &ClientConfig,
64 common_options: CommonOptions,
65 ) -> Self {
66 let retry_policy = config
67 .retry_policy
68 .clone()
69 .unwrap_or_else(|| Arc::new(crate::retry_policy::storage_default()));
70 let backoff_policy = config
71 .backoff_policy
72 .clone()
73 .unwrap_or_else(|| Arc::new(crate::backoff_policy::default()));
74 let retry_throttler = config.retry_throttler.clone();
75 Self::new_with_policies(
76 retry_policy,
77 backoff_policy,
78 retry_throttler,
79 common_options,
80 )
81 }
82
83 pub fn set_read_resume_policy(&mut self, v: Arc<dyn ReadResumePolicy>) {
84 self.common_options.read_resume_policy = v;
85 }
86
87 pub fn read_resume_policy(&self) -> Arc<dyn ReadResumePolicy> {
88 self.common_options.read_resume_policy.clone()
89 }
90
91 pub fn set_resumable_upload_threshold(&mut self, v: usize) {
92 self.common_options.resumable_upload_threshold = v;
93 }
94
95 pub fn resumable_upload_threshold(&self) -> usize {
96 self.common_options.resumable_upload_threshold
97 }
98
99 pub fn set_resumable_upload_buffer_size(&mut self, v: usize) {
100 self.common_options.resumable_upload_buffer_size = v;
101 }
102
103 pub fn set_bidi_attempt_timeout(&mut self, v: Duration) {
104 self.bidi_attempt_timeout = v;
105 }
106
107 pub fn resumable_upload_buffer_size(&self) -> usize {
108 self.common_options.resumable_upload_buffer_size
109 }
110
111 pub fn with_user_agent(&mut self, v: impl Into<String>) {
112 self.user_agent = Some(v.into());
113 }
114
115 fn new_with_policies(
116 retry_policy: Arc<dyn RetryPolicy>,
117 backoff_policy: Arc<dyn BackoffPolicy>,
118 retry_throttler: SharedRetryThrottler,
119 common_options: CommonOptions,
120 ) -> Self {
121 Self {
122 retry_policy,
123 backoff_policy,
124 retry_throttler,
125 common_options,
126 idempotency: None,
127 checksum: Checksum {
128 crc32c: Some(Crc32c::default()),
129 md5_hash: None,
130 },
131 automatic_decompression: false,
132 bidi_attempt_timeout: DEFAULT_BIDI_ATTEMPT_TIMEOUT,
133 user_agent: None,
134 }
135 }
136
137 pub(crate) fn gax(&self) -> google_cloud_gax::options::RequestOptions {
138 let mut options = google_cloud_gax::options::RequestOptions::default();
139 options.set_backoff_policy(self.backoff_policy.clone());
140 options.set_retry_policy(self.retry_policy.clone());
141 options.set_retry_throttler(self.retry_throttler.clone());
142 if let Some(i) = &self.idempotency {
143 options.set_idempotency(*i);
144 }
145 if let Some(s) = &self.user_agent {
146 options.set_user_agent(s);
147 }
148 options
149 }
150}
151
152#[cfg(test)]
153mod tests {
154 use super::*;
155 use crate::storage::client::tests::{MockBackoffPolicy, MockRetryPolicy, MockRetryThrottler};
156
157 #[test]
158 fn gax_policies() {
159 let mut options = RequestOptions::new();
160 options.retry_policy = Arc::new(MockRetryPolicy::new());
161 options.retry_throttler = Arc::new(Mutex::new(MockRetryThrottler::new()));
162 options.backoff_policy = Arc::new(MockBackoffPolicy::new());
163
164 let got = options.gax();
165 assert!(got.backoff_policy().is_some(), "{got:?}");
166 assert!(got.retry_policy().is_some(), "{got:?}");
167 assert!(got.retry_throttler().is_some(), "{got:?}");
168 assert!(got.idempotent().is_none(), "{got:?}");
169
170 let fmt = format!("{got:?}");
171 assert!(fmt.contains("MockBackoffPolicy"), "{fmt}");
172 assert!(fmt.contains("MockRetryPolicy"), "{fmt}");
173 assert!(fmt.contains("MockRetryThrottler"), "{fmt}");
174 }
175
176 #[test]
177 fn gax_idempotency() {
178 let mut options = RequestOptions::new();
179 options.idempotency = Some(true);
180 let got = options.gax();
181 assert_eq!(got.idempotent(), Some(true));
182 }
183
184 #[test]
185 fn gax_user_agent() {
186 let user_agent = "quick_foxes_lazy_dogs/1.2.3";
187 let mut options = RequestOptions::new();
188 options.with_user_agent(user_agent);
189 let got = options.gax();
190 assert_eq!(got.user_agent().as_deref(), Some(user_agent));
191 }
192}