use crate::control::inputs::InputMeta;
use crate::error::SendError;
use crate::io::base::BaseTx;
use crate::utils::CancelToken;
use crate::utils::time::timestamp::now_millis;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::fmt::Debug;
use std::time::Duration;
use uuid::Uuid;
pub trait ModelContext: Send + 'static + Clone {}
pub trait ModelEvent: Send + 'static + Clone {}
#[derive(Clone, Debug)]
pub struct NullModelCtx;
impl ModelContext for NullModelCtx {}
#[derive(Clone, Debug)]
pub struct NullModelEvent;
impl ModelEvent for NullModelEvent {}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum StopKind {
Stop,
Shutdown,
Restart,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ExecutionResult {
Stop,
Shutdown,
Continue,
Relax,
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum StopState {
InProgress,
Done,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum Output<T: Send + 'static> {
Generic(T),
Internal {
sent_at: u64,
corr_id: Uuid,
success: bool,
error: Option<String>,
},
}
impl<T: Send + 'static> Output<T> {
pub fn internal(corr_id: Uuid, success: bool, error: Option<String>) -> Self {
Self::Internal {
sent_at: now_millis(),
corr_id,
success,
error,
}
}
pub fn generic(payload: T) -> Self {
Self::Generic(payload)
}
}
#[derive(Clone, Debug)]
pub struct NullOutputTx;
impl BaseTx for NullOutputTx {
type EventType = Output<()>;
fn try_send(
&mut self,
_a: Self::EventType,
) -> std::result::Result<(), SendError<Self::EventType>> {
Ok(())
}
fn send(
&mut self,
_a: Self::EventType,
_cancel: &CancelToken,
_timeout: Option<Duration>,
) -> std::result::Result<(), SendError<Self::EventType>> {
Ok(())
}
}
pub trait BaseModel: Sized {
type Config: Send + Clone + for<'a> Deserialize<'a> + Any;
type OutputTx: BaseTx<EventType = Output<Self::OutputEvent>> + Clone;
type OutputEvent: Send + 'static + Clone;
type Event: ModelEvent;
type Ctx: ModelContext;
fn initialize(
ctx: Self::Ctx,
config: Self::Config,
reserved_core_id: Option<usize>,
output_tx: Self::OutputTx,
cancel_token: CancelToken,
) -> Result<Self>;
fn execute(&mut self) -> ExecutionResult;
fn on_event(&mut self, event: Self::Event, meta: Option<InputMeta>);
fn stop(&mut self, kind: StopKind) -> StopState;
fn hot_reload(&mut self, config: &Self::Config) -> Result<()> {
let _ = config;
Ok(())
}
}