use super::LoadSignal;
use crate::errors::CrawlError;
use std::{fmt, sync::Arc, time::Duration};
#[derive(Clone)]
#[non_exhaustive]
#[must_use = "snapshotter options do nothing unless passed to Snapshotter::new"]
pub struct SnapshotterOptions {
pub signals: Vec<Arc<dyn LoadSignal>>,
pub window: Duration,
}
impl Default for SnapshotterOptions {
fn default() -> Self {
Self {
signals: Vec::new(),
window: Duration::from_secs(30),
}
}
}
impl fmt::Debug for SnapshotterOptions {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter
.debug_struct("SnapshotterOptions")
.field("signal_count", &self.signals.len())
.field("window", &self.window)
.finish()
}
}
pub struct Snapshotter {
options: SnapshotterOptions,
}
impl Snapshotter {
pub fn new(options: SnapshotterOptions) -> Self {
Self { options }
}
pub fn signals(&self) -> &[Arc<dyn LoadSignal>] {
&self.options.signals
}
pub fn window(&self) -> Duration {
self.options.window
}
pub async fn start(&self) -> Result<(), CrawlError> {
for signal in &self.options.signals {
signal.start().await?;
}
Ok(())
}
pub async fn stop(&self) -> Result<(), CrawlError> {
let mut first_error = None;
for signal in &self.options.signals {
if let Err(error) = signal.stop().await {
if first_error.is_none() {
first_error = Some(error);
}
}
}
match first_error {
Some(error) => Err(error),
None => Ok(()),
}
}
}