1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
use std::time::Duration;
/// Configuration for a [`Client`]'s reconnect behaviour.
///
/// ```
/// # use std::time::Duration;
/// # use eventsource_client::ReconnectOptions;
/// #
/// let reconnect_options = ReconnectOptions::reconnect(true)
/// .retry_initial(false)
/// .delay(Duration::from_secs(1))
/// .backoff_factor(2)
/// .delay_max(Duration::from_secs(60))
/// .build();
/// ```
///
/// See [`default()`] for a description of the default behaviour. See
/// [`ReconnectOptionsBuilder`] for descriptions of each configurable parameter.
///
/// [`Client`]: struct.Client.html
/// [`default()`]: #method.default
/// [`ReconnectOptionsBuilder`]: struct.ReconnectOptionsBuilder.html
#[derive(Clone, Debug)]
pub struct ReconnectOptions {
pub(crate) retry_initial: bool,
pub(crate) reconnect: bool,
pub(crate) delay: Duration,
pub(crate) backoff_factor: u32,
pub(crate) delay_max: Duration,
}
impl ReconnectOptions {
/// Start building a `ReconnectOptions`, by enabling or disabling
/// reconnection on stream error.
///
/// If `reconnect` is `true` (the [default]), the client will automatically
/// try to reconnect if the stream ends due to an error. If it is `false`,
/// the client will stop receiving events after an error.
///
/// [default]: #method.default
pub fn reconnect(reconnect: bool) -> ReconnectOptionsBuilder {
ReconnectOptionsBuilder::new(reconnect)
}
}
impl Default for ReconnectOptions {
/// The default reconnect behaviour is to automatically try to reconnect if
/// the stream ends due to an error, but not to retry if the initial
/// connection fails.
///
/// The client will wait before each reconnect attempt, to allow time for
/// the error condition to be resolved (e.g. for the SSE server to restart
/// if it went down). It will wait 1 second before the first attempt, and
/// then back off exponentially, up to a maximum wait of 1 minute.
fn default() -> ReconnectOptions {
ReconnectOptions {
retry_initial: false,
reconnect: true,
delay: Duration::from_secs(1),
backoff_factor: 2,
delay_max: Duration::from_secs(60),
}
}
}
/// Builder for [`ReconnectOptions`].
///
/// [`ReconnectOptions`]: struct.ReconnectOptions.html
pub struct ReconnectOptionsBuilder {
opts: ReconnectOptions,
}
impl ReconnectOptionsBuilder {
pub fn new(reconnect: bool) -> Self {
let opts = ReconnectOptions {
reconnect,
..Default::default()
};
Self { opts }
}
/// Configure whether to retry if the initial connection to the server
/// fails.
///
/// If `true`, the client will automatically retry the connection, with the
/// same delay and backoff behaviour as for reconnects due to stream error.
/// If `false` (the [default]), the client will not retry the initial
/// connection.
///
/// [default]: struct.ReconnectOptions.html#method.default
pub fn retry_initial(mut self, retry: bool) -> Self {
self.opts.retry_initial = retry;
self
}
/// Configure the initial delay before trying to reconnect (the [default] is
/// 1 second).
///
/// After an error, the client will wait this long before the first attempt
/// to reconnect. Subsequent reconnect attempts may wait longer, depending
/// on the [`backoff_factor`].
///
/// [default]: struct.ReconnectOptions.html#method.default
/// [`backoff_factor`]: #method.backoff_factor
pub fn delay(mut self, delay: Duration) -> Self {
self.opts.delay = delay;
self
}
/// Configure the factor by which delays between reconnect attempts will
/// exponentially increase, up to [`delay_max`]. The [default] factor is 2,
/// so each reconnect attempt will wait twice as long as the previous one.
///
/// Set this to 1 to disable exponential backoff (i.e. to make reconnect
/// attempts at regular intervals equal to the configured [`delay`]).
///
/// [`delay_max`]: #method.delay_max
/// [default]: struct.ReconnectOptions.html#method.default
/// [`delay`]: #method.delay
pub fn backoff_factor(mut self, factor: u32) -> Self {
self.opts.backoff_factor = factor;
self
}
/// Configure the maximum delay between reconnects (the [default] is 1
/// minute). The exponential backoff configured by [`backoff_factor`] will
/// not cause a delay greater than this value.
///
/// [default]: struct.ReconnectOptions.html#method.default
/// [`backoff_factor`]: #method.backoff_factor
pub fn delay_max(mut self, max: Duration) -> Self {
self.opts.delay_max = max;
self
}
/// Finish building the `ReconnectOptions`.
pub fn build(self) -> ReconnectOptions {
self.opts
}
}