use std::sync::Arc;
use std::time::Duration;
use crate::bus::{Bus, RunOptions};
use crate::microsvc::Service;
use crate::outbox_worker::{
drain_worker_id, BusPublisher, OutboxDispatcher, OutboxDrainRunner, OutboxStore,
};
pub fn spawn_outbox_publish_loop<S, B>(
store: S,
bus: Arc<B>,
service_name: impl Into<String>,
lease: Duration,
max_attempts: u32,
) where
S: OutboxStore + 'static,
B: Bus + Send + Sync + 'static,
{
let dispatcher = OutboxDispatcher::new(
store,
BusPublisher::new(bus),
drain_worker_id(),
lease,
max_attempts,
)
.with_service(service_name);
let _handle = OutboxDrainRunner::new(dispatcher)
.with_batch_size(32)
.with_poll_interval(Duration::from_millis(25))
.with_error_backoff(Duration::from_millis(100))
.spawn();
}
pub const CONSUMER_IDLE_POLL: Duration = Duration::from_millis(25);
pub fn spawn_service_consumer_loop<F>(build_service: F)
where
F: Fn() -> Service + Send + Sync + 'static,
{
tokio::spawn(async move {
loop {
let service = build_service();
match service.run(RunOptions::idempotent()).await {
Ok(()) => {
eprintln!(
"consumer: bus drained to idle; not reconstructing Service. \
Long-running SQL hosts must call with_idle_poll({CONSUMER_IDLE_POLL:?})"
);
return;
}
Err(e) => {
eprintln!("consumer: {e}");
tokio::time::sleep(Duration::from_millis(100)).await;
}
}
}
});
}