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 gax::{
21 backoff_policy::BackoffPolicy,
22 retry_policy::RetryPolicy,
23 retry_throttler::{AdaptiveThrottler, SharedRetryThrottler},
24};
25use gaxi::options::ClientConfig;
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}
47
48impl RequestOptions {
49 pub(crate) fn new() -> Self {
50 let retry_policy = Arc::new(crate::retry_policy::storage_default());
51 let backoff_policy = Arc::new(crate::backoff_policy::default());
52 let retry_throttler = Arc::new(Mutex::new(AdaptiveThrottler::default()));
53 Self::new_with_policies(
54 retry_policy,
55 backoff_policy,
56 retry_throttler,
57 CommonOptions::new(),
58 )
59 }
60
61 pub(crate) fn new_with_client_config(
62 config: &ClientConfig,
63 common_options: CommonOptions,
64 ) -> Self {
65 let retry_policy = config
66 .retry_policy
67 .clone()
68 .unwrap_or_else(|| Arc::new(crate::retry_policy::storage_default()));
69 let backoff_policy = config
70 .backoff_policy
71 .clone()
72 .unwrap_or_else(|| Arc::new(crate::backoff_policy::default()));
73 let retry_throttler = config.retry_throttler.clone();
74 Self::new_with_policies(
75 retry_policy,
76 backoff_policy,
77 retry_throttler,
78 common_options,
79 )
80 }
81
82 pub fn set_read_resume_policy(&mut self, v: Arc<dyn ReadResumePolicy>) {
83 self.common_options.read_resume_policy = v;
84 }
85
86 pub fn read_resume_policy(&self) -> Arc<dyn ReadResumePolicy> {
87 self.common_options.read_resume_policy.clone()
88 }
89
90 pub fn set_resumable_upload_threshold(&mut self, v: usize) {
91 self.common_options.resumable_upload_threshold = v;
92 }
93
94 pub fn resumable_upload_threshold(&self) -> usize {
95 self.common_options.resumable_upload_threshold
96 }
97
98 pub fn set_resumable_upload_buffer_size(&mut self, v: usize) {
99 self.common_options.resumable_upload_buffer_size = v;
100 }
101
102 pub fn set_bidi_attempt_timeout(&mut self, v: Duration) {
103 self.bidi_attempt_timeout = v;
104 }
105
106 pub fn resumable_upload_buffer_size(&self) -> usize {
107 self.common_options.resumable_upload_buffer_size
108 }
109
110 fn new_with_policies(
111 retry_policy: Arc<dyn RetryPolicy>,
112 backoff_policy: Arc<dyn BackoffPolicy>,
113 retry_throttler: SharedRetryThrottler,
114 common_options: CommonOptions,
115 ) -> Self {
116 Self {
117 retry_policy,
118 backoff_policy,
119 retry_throttler,
120 common_options,
121 idempotency: None,
122 checksum: Checksum {
123 crc32c: Some(Crc32c::default()),
124 md5_hash: None,
125 },
126 automatic_decompression: false,
127 bidi_attempt_timeout: DEFAULT_BIDI_ATTEMPT_TIMEOUT,
128 }
129 }
130
131 pub(crate) fn gax(&self) -> gax::options::RequestOptions {
132 let mut options = gax::options::RequestOptions::default();
133 options.set_backoff_policy(self.backoff_policy.clone());
134 options.set_retry_policy(self.retry_policy.clone());
135 options.set_retry_throttler(self.retry_throttler.clone());
136 if let Some(ref i) = self.idempotency {
137 options.set_idempotency(*i);
138 }
139 options
140 }
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146 use crate::storage::client::tests::{MockBackoffPolicy, MockRetryPolicy, MockRetryThrottler};
147
148 #[test]
149 fn gax_policies() {
150 let mut options = RequestOptions::new();
151 options.retry_policy = Arc::new(MockRetryPolicy::new());
152 options.retry_throttler = Arc::new(Mutex::new(MockRetryThrottler::new()));
153 options.backoff_policy = Arc::new(MockBackoffPolicy::new());
154
155 let got = options.gax();
156 assert!(got.backoff_policy().is_some(), "{got:?}");
157 assert!(got.retry_policy().is_some(), "{got:?}");
158 assert!(got.retry_throttler().is_some(), "{got:?}");
159 assert!(got.idempotent().is_none(), "{got:?}");
160
161 let fmt = format!("{got:?}");
162 assert!(fmt.contains("MockBackoffPolicy"), "{fmt}");
163 assert!(fmt.contains("MockRetryPolicy"), "{fmt}");
164 assert!(fmt.contains("MockRetryThrottler"), "{fmt}");
165 }
166
167 #[test]
168 fn gax_idempotency() {
169 let mut options = RequestOptions::new();
170 options.idempotency = Some(true);
171 let got = options.gax();
172 assert_eq!(got.idempotent(), Some(true));
173 }
174}