use std::sync::Arc;
use super::DurableProcessWorker;
use super::process::ProcessRegistry;
use crate::PluginError;
#[derive(Clone)]
pub struct ProcessWorkDriver {
registry: Arc<dyn ProcessRegistry>,
run_handle: Arc<dyn ProcessRunHandle>,
}
impl ProcessWorkDriver {
pub fn new(registry: Arc<dyn ProcessRegistry>, run_handle: Arc<dyn ProcessRunHandle>) -> Self {
Self {
registry,
run_handle,
}
}
pub fn inline(registry: Arc<dyn ProcessRegistry>, worker: DurableProcessWorker) -> Self {
Self::new(registry, Arc::new(InlineProcessRunHandle::new(worker)))
}
pub fn process_registry(&self) -> Arc<dyn ProcessRegistry> {
Arc::clone(&self.registry)
}
pub async fn claim_and_run_pending(&self, reason: &str) -> Result<(), PluginError> {
if let Err(err) = self.run_handle.claim_and_run_pending().await {
tracing::warn!("process work drive ({reason}) failed: {err}");
return Err(err);
}
Ok(())
}
}
#[async_trait::async_trait]
pub trait ProcessRunHandle: Send + Sync {
async fn claim_and_run_pending(&self) -> Result<(), PluginError>;
}
pub struct InlineProcessRunHandle {
worker: DurableProcessWorker,
}
impl InlineProcessRunHandle {
pub fn new(worker: DurableProcessWorker) -> Self {
Self { worker }
}
}
#[async_trait::async_trait]
impl ProcessRunHandle for InlineProcessRunHandle {
async fn claim_and_run_pending(&self) -> Result<(), PluginError> {
self.worker.drive_pending_processes().await
}
}