use std::{collections::BTreeMap, sync::Arc, time::Duration};
use futures::{future::BoxFuture, stream::BoxStream};
use miette::Result;
use serde_json::Value;
use crate::{canopy::CanopyClient, context::InternalContext};
#[derive(Clone)]
pub struct TaskContext {
pub pg_pool: Option<bestool_postgres::pool::PgPool>,
pub http_client: reqwest::Client,
pub canopy_client: Option<Arc<CanopyClient>>,
pub reload: tokio::sync::watch::Receiver<u64>,
pub restart: Option<crate::daemon::RestartTrigger>,
pub query: BTreeMap<String, String>,
}
impl TaskContext {
pub(crate) fn from_internal(ctx: &InternalContext) -> Self {
Self {
pg_pool: ctx.pg_pool.clone(),
http_client: ctx.http_client.clone(),
canopy_client: ctx.canopy_client.clone(),
reload: ctx.reload.clone(),
restart: ctx.restart.clone(),
query: BTreeMap::new(),
}
}
}
pub trait BackgroundTask: Send + Sync + 'static {
fn name(&self) -> &'static str;
fn interval(&self) -> Duration;
fn run<'a>(&'a self, ctx: &'a TaskContext) -> BoxFuture<'a, Result<()>>;
fn http_endpoints(&self) -> Vec<TaskEndpoint> {
Vec::new()
}
}
pub struct TaskEndpoint {
pub name: &'static str,
pub handler: TaskEndpointHandler,
}
pub type TaskEndpointHandler =
Arc<dyn Fn(TaskContext) -> BoxFuture<'static, TaskEndpointResponse> + Send + Sync + 'static>;
pub enum TaskEndpointResponse {
Json(Value),
JsonLines(BoxStream<'static, Value>),
Error {
status: u16,
message: String,
},
}