mod buffered;
mod error;
mod http;
pub use buffered::{BufferedRecorder, BufferedStats, OverflowPolicy};
pub use error::{DrainTimeout, HttpError, RecordError};
pub use http::{HttpRecorder, DEFAULT_REQUEST_TIMEOUT};
use std::future::Future;
use std::time::Duration;
use crate::event::Event;
pub const DEFAULT_BASE_URL: &str = "https://api.everscribe.io";
pub trait Recorder {
fn record(&self, event: Event) -> impl Future<Output = Result<(), RecordError>> + Send;
}
impl<T> Recorder for std::sync::Arc<T>
where
T: Recorder + Send + Sync + ?Sized,
{
fn record(&self, event: Event) -> impl Future<Output = Result<(), RecordError>> + Send {
(**self).record(event)
}
}
pub trait BatchRecorder: Send + Sync + 'static {
fn record_batch(
&self,
events: Vec<Event>,
) -> impl Future<Output = Result<(), RecordError>> + Send;
}
#[derive(Clone, Debug)]
pub struct RecorderOptions {
pub base_url: String,
pub request_timeout: Duration,
pub auto_idempotency_key: bool,
pub buffer_size: usize,
pub flush_size: usize,
pub flush_interval: Duration,
pub flush_timeout: Duration,
pub overflow: OverflowPolicy,
pub drain_timeout: Duration,
}
impl Default for RecorderOptions {
fn default() -> Self {
RecorderOptions {
base_url: DEFAULT_BASE_URL.to_string(),
request_timeout: DEFAULT_REQUEST_TIMEOUT,
auto_idempotency_key: false,
buffer_size: 1000,
flush_size: 100,
flush_interval: Duration::from_secs(5),
flush_timeout: Duration::from_secs(30),
overflow: OverflowPolicy::DropNewest,
drain_timeout: Duration::from_secs(30),
}
}
}
pub fn new(
project_id: impl Into<String>,
api_key: impl Into<String>,
opts: RecorderOptions,
) -> BufferedRecorder {
let inner = HttpRecorder::new(project_id, api_key, &opts);
BufferedRecorder::new(inner, &opts)
}