aws_smithy_runtime/client/http/body/minimum_throughput/
options.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6use super::Throughput;
7use aws_smithy_runtime_api::client::stalled_stream_protection::{
8    StalledStreamProtectionConfig, DEFAULT_GRACE_PERIOD,
9};
10use std::time::Duration;
11
12/// A collection of options for configuring a [`MinimumThroughputBody`](super::MinimumThroughputDownloadBody).
13#[derive(Debug, Clone)]
14pub struct MinimumThroughputBodyOptions {
15    /// The minimum throughput that is acceptable.
16    minimum_throughput: Throughput,
17
18    /// The 'grace period' after which the minimum throughput will be enforced.
19    ///
20    /// If this is set to 0, the minimum throughput will be enforced immediately.
21    ///
22    /// If this is set to a positive value, whenever throughput is below the minimum throughput,
23    /// a timer is started. If the timer expires before throughput rises above the minimum,
24    /// an error is emitted.
25    ///
26    /// It is recommended to set this to a small value (e.g. 200ms) to avoid issues during
27    /// stream-startup.
28    grace_period: Duration,
29
30    /// The period of time to consider when computing the throughput
31    ///
32    /// This SHOULD be longer than the check interval, or stuck-streams may evade detection.
33    check_window: Duration,
34}
35
36impl MinimumThroughputBodyOptions {
37    /// Create a new builder.
38    pub fn builder() -> MinimumThroughputBodyOptionsBuilder {
39        Default::default()
40    }
41
42    /// Convert this struct into a builder.
43    pub fn to_builder(self) -> MinimumThroughputBodyOptionsBuilder {
44        MinimumThroughputBodyOptionsBuilder::new()
45            .minimum_throughput(self.minimum_throughput)
46            .grace_period(self.grace_period)
47    }
48
49    /// The throughput check grace period.
50    ///
51    /// If throughput is below the minimum for longer than this period, an error is emitted.
52    ///
53    /// If this is set to 0, the minimum throughput will be enforced immediately.
54    pub fn grace_period(&self) -> Duration {
55        self.grace_period
56    }
57
58    /// The minimum acceptable throughput
59    pub fn minimum_throughput(&self) -> Throughput {
60        self.minimum_throughput
61    }
62
63    pub(crate) fn check_window(&self) -> Duration {
64        self.check_window
65    }
66
67    /// Not used. Always returns `Duration::from_millis(500)`.
68    #[deprecated(note = "No longer used. Always returns Duration::from_millis(500)")]
69    pub fn check_interval(&self) -> Duration {
70        Duration::from_millis(500)
71    }
72}
73
74const DEFAULT_MINIMUM_THROUGHPUT: Throughput = Throughput {
75    bytes_read: 1,
76    per_time_elapsed: Duration::from_secs(1),
77};
78
79const DEFAULT_CHECK_WINDOW: Duration = Duration::from_secs(1);
80
81impl Default for MinimumThroughputBodyOptions {
82    fn default() -> Self {
83        Self {
84            minimum_throughput: DEFAULT_MINIMUM_THROUGHPUT,
85            grace_period: DEFAULT_GRACE_PERIOD,
86            check_window: DEFAULT_CHECK_WINDOW,
87        }
88    }
89}
90
91/// A builder for [`MinimumThroughputBodyOptions`]
92#[derive(Debug, Default, Clone)]
93pub struct MinimumThroughputBodyOptionsBuilder {
94    minimum_throughput: Option<Throughput>,
95    check_window: Option<Duration>,
96    grace_period: Option<Duration>,
97}
98
99impl MinimumThroughputBodyOptionsBuilder {
100    /// Create a new `MinimumThroughputBodyOptionsBuilder`.
101    pub fn new() -> Self {
102        Default::default()
103    }
104
105    /// Set the amount of time that throughput my fall below minimum before an error is emitted.
106    ///
107    /// If throughput rises above the minimum, the timer is reset.
108    pub fn grace_period(mut self, grace_period: Duration) -> Self {
109        self.set_grace_period(Some(grace_period));
110        self
111    }
112
113    /// Set the amount of time that throughput my fall below minimum before an error is emitted.
114    ///
115    /// If throughput rises above the minimum, the timer is reset.
116    pub fn set_grace_period(&mut self, grace_period: Option<Duration>) -> &mut Self {
117        self.grace_period = grace_period;
118        self
119    }
120
121    /// Set the minimum allowable throughput.
122    pub fn minimum_throughput(mut self, minimum_throughput: Throughput) -> Self {
123        self.set_minimum_throughput(Some(minimum_throughput));
124        self
125    }
126
127    /// Set the minimum allowable throughput.
128    pub fn set_minimum_throughput(&mut self, minimum_throughput: Option<Throughput>) -> &mut Self {
129        self.minimum_throughput = minimum_throughput;
130        self
131    }
132
133    /// No longer used. The check interval is now based on the check window (not currently configurable).
134    #[deprecated(
135        note = "No longer used. The check interval is now based on the check window (not currently configurable). Open an issue if you need to configure the check window."
136    )]
137    pub fn check_interval(self, _check_interval: Duration) -> Self {
138        self
139    }
140
141    /// No longer used. The check interval is now based on the check window (not currently configurable).
142    #[deprecated(
143        note = "No longer used. The check interval is now based on the check window (not currently configurable). Open an issue if you need to configure the check window."
144    )]
145    pub fn set_check_interval(&mut self, _check_interval: Option<Duration>) -> &mut Self {
146        self
147    }
148
149    #[allow(unused)]
150    pub(crate) fn check_window(mut self, check_window: Duration) -> Self {
151        self.set_check_window(Some(check_window));
152        self
153    }
154    #[allow(unused)]
155    pub(crate) fn set_check_window(&mut self, check_window: Option<Duration>) -> &mut Self {
156        self.check_window = check_window;
157        self
158    }
159
160    /// Build this builder, producing a [`MinimumThroughputBodyOptions`].
161    ///
162    /// Unset fields will be set with defaults.
163    pub fn build(self) -> MinimumThroughputBodyOptions {
164        MinimumThroughputBodyOptions {
165            grace_period: self.grace_period.unwrap_or(DEFAULT_GRACE_PERIOD),
166            minimum_throughput: self
167                .minimum_throughput
168                .unwrap_or(DEFAULT_MINIMUM_THROUGHPUT),
169            check_window: self.check_window.unwrap_or(DEFAULT_CHECK_WINDOW),
170        }
171    }
172}
173
174impl From<StalledStreamProtectionConfig> for MinimumThroughputBodyOptions {
175    fn from(value: StalledStreamProtectionConfig) -> Self {
176        MinimumThroughputBodyOptions {
177            grace_period: value.grace_period(),
178            minimum_throughput: DEFAULT_MINIMUM_THROUGHPUT,
179            check_window: DEFAULT_CHECK_WINDOW,
180        }
181    }
182}