use crate::error::Error;
use crate::hosts::solr_host::SolrHost;
use async_trait::async_trait;
use std::borrow::Cow;
use std::time::Duration;
#[derive(Clone)]
pub struct SolrSingleServerHost {
pub host: String,
}
#[async_trait]
impl SolrHost for SolrSingleServerHost {
async fn get_solr_node<'a>(&'a self) -> Result<Cow<'a, str>, Error> {
Ok(Cow::Borrowed(&self.host))
}
}
impl SolrSingleServerHost {
pub fn new<S: Into<String>>(host: S) -> SolrSingleServerHost {
SolrSingleServerHost { host: host.into() }
}
}
#[derive(Clone)]
pub struct SolrMultipleServerHost {
pub hosts: Vec<String>,
pub timeout: Duration,
}
#[async_trait]
impl SolrHost for SolrMultipleServerHost {
async fn get_solr_node<'a>(&'a self) -> Result<Cow<'a, str>, Error> {
let mut server_indices: Vec<usize> = (0..self.hosts.len()).collect();
if server_indices.is_empty() {
return Err(Error::SolrSetupError("No Solr Host Specified".to_string()));
}
fastrand::shuffle(&mut server_indices);
for i in server_indices {
match self.hosts.get(i) {
None => continue,
Some(r) => {
let client = reqwest::Client::new();
let res = client
.get(format!("{}/solr/", r))
.timeout(self.timeout)
.send()
.await;
if res.is_err() {
continue;
}
return Ok(Cow::Borrowed(r));
}
}
}
Err(Error::SolrSetupError("No Solr Host answered".to_string()))
}
}
impl SolrMultipleServerHost {
pub fn new<S: Into<String>, V: IntoIterator<Item = S>>(
hosts: V,
timeout: Duration,
) -> SolrMultipleServerHost {
SolrMultipleServerHost {
hosts: hosts.into_iter().map(|s| s.into()).collect(),
timeout,
}
}
}