#[allow(unused_imports)]
use crate::experimental::BackendCreationError;
use crate::Backend;
use http::uri::PathAndQuery;
use std::time::Duration;
#[derive(Clone)]
pub struct HealthcheckBuilder {
host: String,
method: String,
path: PathAndQuery,
expected_status: u16,
window: u32,
threshold: u32,
initial: u32,
interval_ms: Duration,
timeout_ms: Duration,
}
#[cfg(target_env = "p1")]
const URL_SIZE_LIMIT: usize = 8192;
#[cfg(target_env = "p1")]
const METHOD_SIZE_LIMIT: usize = 8192;
#[cfg(target_env = "p1")]
const WINDOW_LIMIT: u32 = 15; #[cfg(target_env = "p1")]
const INTERVAL_MAX_MS: u128 = 3600000; #[cfg(target_env = "p1")]
const INTERVAL_MIN_MS: u128 = 1000; #[cfg(target_env = "p1")]
const TIMEOUT_MAX_MS: u128 = 3600000; #[cfg(target_env = "p1")]
const TIMEOUT_MIN_MS: u128 = 1000;
impl HealthcheckBuilder {
#[doc = include_str!("../../docs/snippets/healthcheck-builder.md")]
pub fn new(host: impl ToString) -> Self {
HealthcheckBuilder {
host: host.to_string(),
method: "GET".to_string(),
path: PathAndQuery::from_static("/"),
expected_status: 200,
window: 5,
threshold: 3,
initial: 4,
interval_ms: Duration::from_millis(15000),
timeout_ms: Duration::from_millis(5000),
}
}
#[cfg(target_env = "p1")]
pub fn validate(&self) -> Result<(), BackendCreationError> {
let host_size: usize = self.host.len();
let path_size: usize = self.path.path().len();
if self.host.is_empty() {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"host:{} is empty",
self.host
)));
}
if (host_size + path_size) > URL_SIZE_LIMIT {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"host:{} or path:{} is too large",
self.host,
self.path.path()
)));
}
let method_size: usize = self.method.len();
if method_size > METHOD_SIZE_LIMIT {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"method:{} is too large",
self.method
)));
}
if self.window > WINDOW_LIMIT {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"window:{} is too large",
self.window
)));
}
if self.window < self.threshold {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"threshold:{} is greater than window:{}",
self.threshold, self.window
)));
}
if self.window < self.initial {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"initial:{} is greater than window:{}",
self.initial, self.window
)));
}
if !(INTERVAL_MIN_MS..INTERVAL_MAX_MS).contains(&self.interval_ms.as_millis()) {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"interval_ms:{} is not within {}, {}",
self.interval_ms.as_millis(),
INTERVAL_MIN_MS,
INTERVAL_MAX_MS
)));
}
if !(TIMEOUT_MIN_MS..TIMEOUT_MAX_MS).contains(&self.timeout_ms.as_millis()) {
return Err(BackendCreationError::InvalidHealthcheckValue(format!(
"timeout_ms:{} is not within {}, {}",
self.timeout_ms.as_millis(),
TIMEOUT_MIN_MS,
TIMEOUT_MAX_MS
)));
}
Ok(())
}
pub fn get_host(&self) -> &str {
self.host.as_str()
}
pub fn get_method(&self) -> &str {
self.method.as_str()
}
pub fn get_path(&self) -> &PathAndQuery {
&self.path
}
pub fn get_expected_status(&self) -> u16 {
self.expected_status
}
pub fn get_window(&self) -> u32 {
self.window
}
pub fn get_threshold(&self) -> u32 {
self.threshold
}
pub fn get_initial(&self) -> u32 {
self.initial
}
pub fn get_interval_ms(&self) -> Duration {
self.interval_ms
}
pub fn get_timeout_ms(&self) -> Duration {
self.timeout_ms
}
pub fn host(mut self, name: impl ToString) -> Self {
self.host = name.to_string();
self
}
pub fn method(mut self, value: impl ToString) -> Self {
self.method = value.to_string();
self
}
pub fn path(mut self, value: impl ToString) -> Self {
self.path = PathAndQuery::from_maybe_shared(value.to_string()).expect("Improper path set");
self
}
pub fn expected_status(mut self, value: u16) -> Self {
self.expected_status = value;
self
}
pub fn window(mut self, value: u32) -> Self {
self.window = value;
self
}
pub fn threshold(mut self, value: u32) -> Self {
self.threshold = value;
self
}
pub fn initial(mut self, value: u32) -> Self {
self.initial = value;
self
}
pub fn interval_ms(mut self, value: Duration) -> Self {
self.interval_ms = value;
self
}
pub fn timeout_ms(mut self, value: Duration) -> Self {
self.timeout_ms = value;
self
}
}
impl Backend {
#[doc = include_str!("../../docs/snippets/healthcheck-builder.md")]
pub fn healthcheck_builder(host: impl ToString) -> HealthcheckBuilder {
HealthcheckBuilder::new(host.to_string())
}
}