use super::processor::{
EventProcessor, EventProcessorError, EventProcessorImpl, NullEventProcessor,
};
use super::sender::{EventSender, ReqwestEventSender};
use super::EventsConfiguration;
use crate::service_endpoints;
use std::sync::Arc;
use std::time::Duration;
use thiserror::Error;
const DEFAULT_FLUSH_POLL_INTERVAL: Duration = Duration::from_secs(5);
const DEFAULT_EVENT_CAPACITY: usize = 500;
const DEFAULT_USER_KEY_SIZE: usize = 1000;
const DEFAULT_USER_KEYS_FLUSH_INTERVAL: Duration = Duration::from_secs(5 * 60);
#[non_exhaustive]
#[derive(Debug, Error)]
pub enum BuildError {
#[error("event processor factory failed to build: {0}")]
InvalidConfig(String),
#[error(transparent)]
FailedToStart(EventProcessorError),
}
pub trait EventProcessorFactory {
fn build(
&self,
endpoints: &service_endpoints::ServiceEndpoints,
sdk_key: &str,
) -> Result<Arc<dyn EventProcessor>, BuildError>;
fn to_owned(&self) -> Box<dyn EventProcessorFactory>;
}
#[derive(Clone)]
pub struct EventProcessorBuilder {
capacity: usize,
flush_interval: Duration,
user_keys_capacity: usize,
user_keys_flush_interval: Duration,
inline_users_in_events: bool,
event_sender: Option<Arc<dyn EventSender>>,
}
impl EventProcessorFactory for EventProcessorBuilder {
fn build(
&self,
endpoints: &service_endpoints::ServiceEndpoints,
sdk_key: &str,
) -> Result<Arc<dyn EventProcessor>, BuildError> {
let url = format!("{}/bulk", endpoints.events_base_url());
let url = reqwest::Url::parse(&url).map_err(|e| {
BuildError::InvalidConfig(format!("couldn't parse events_base_url: {}", e))
})?;
let http = reqwest::Client::builder().build().map_err(|e| {
BuildError::InvalidConfig(format!("unable to build reqwest client: {}", e))
})?;
let event_sender = match &self.event_sender {
Some(event_sender) => event_sender.clone(),
_ => Arc::new(ReqwestEventSender::new(http, url, sdk_key)),
};
let events_configuration = EventsConfiguration {
event_sender,
capacity: self.capacity,
flush_interval: self.flush_interval,
inline_users_in_events: self.inline_users_in_events,
user_keys_capacity: self.user_keys_capacity,
user_keys_flush_interval: self.user_keys_flush_interval,
};
let events_processor =
EventProcessorImpl::new(events_configuration).map_err(BuildError::FailedToStart)?;
Ok(Arc::new(events_processor))
}
fn to_owned(&self) -> Box<dyn EventProcessorFactory> {
Box::new(self.clone())
}
}
impl EventProcessorBuilder {
pub fn new() -> Self {
Self {
capacity: DEFAULT_EVENT_CAPACITY,
flush_interval: DEFAULT_FLUSH_POLL_INTERVAL,
user_keys_capacity: DEFAULT_USER_KEY_SIZE,
user_keys_flush_interval: DEFAULT_USER_KEYS_FLUSH_INTERVAL,
inline_users_in_events: false,
event_sender: None,
}
}
pub fn capacity(&mut self, capacity: usize) -> &mut Self {
self.capacity = capacity;
self
}
pub fn flush_interval(&mut self, flush_interval: Duration) -> &mut Self {
self.flush_interval = flush_interval;
self
}
pub fn user_keys_capacity(&mut self, user_keys_capacity: usize) -> &mut Self {
self.user_keys_capacity = user_keys_capacity;
self
}
pub fn user_keys_flush_interval(&mut self, user_keys_flush_interval: Duration) -> &mut Self {
self.user_keys_flush_interval = user_keys_flush_interval;
self
}
pub fn inline_users_in_events(&mut self, inline_users_in_events: bool) -> &mut Self {
self.inline_users_in_events = inline_users_in_events;
self
}
#[cfg(test)]
pub fn event_sender(&mut self, event_sender: Arc<dyn EventSender>) -> &mut Self {
self.event_sender = Some(event_sender);
self
}
}
impl Default for EventProcessorBuilder {
fn default() -> Self {
Self::new()
}
}
#[derive(Clone)]
pub struct NullEventProcessorBuilder {}
impl EventProcessorFactory for NullEventProcessorBuilder {
fn build(
&self,
_: &service_endpoints::ServiceEndpoints,
_: &str,
) -> Result<Arc<dyn EventProcessor>, BuildError> {
Ok(Arc::new(NullEventProcessor::new()))
}
fn to_owned(&self) -> Box<dyn EventProcessorFactory> {
Box::new(self.clone())
}
}
impl NullEventProcessorBuilder {
pub fn new() -> Self {
Self {}
}
}
impl Default for NullEventProcessorBuilder {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_builder_has_correct_defaults() {
let builder = EventProcessorBuilder::new();
assert_eq!(builder.capacity, DEFAULT_EVENT_CAPACITY);
assert_eq!(builder.flush_interval, DEFAULT_FLUSH_POLL_INTERVAL);
}
#[test]
fn capacity_can_be_adjusted() {
let mut builder = EventProcessorBuilder::new();
builder.capacity(1234);
assert_eq!(builder.capacity, 1234);
}
#[test]
fn flush_interval_can_be_adjusted() {
let mut builder = EventProcessorBuilder::new();
builder.flush_interval(Duration::from_secs(1234));
assert_eq!(builder.flush_interval, Duration::from_secs(1234));
}
#[test]
fn user_keys_capacity_can_be_adjusted() {
let mut builder = EventProcessorBuilder::new();
builder.user_keys_capacity(1234);
assert_eq!(builder.user_keys_capacity, 1234);
}
#[test]
fn user_keys_flush_interval_can_be_adjusted() {
let mut builder = EventProcessorBuilder::new();
builder.user_keys_flush_interval(Duration::from_secs(1000));
assert_eq!(builder.user_keys_flush_interval, Duration::from_secs(1000));
}
#[test]
fn inline_users_in_events_can_be_adjusted() {
let mut builder = EventProcessorBuilder::new();
builder.inline_users_in_events(true);
assert!(builder.inline_users_in_events);
}
}