use cloacina_workflow::{Context, Trigger, TriggerError, TriggerResult};
use cloacina_workflow_plugin::{
TriggerInvokeRequest, TriggerInvokeResult, METHOD_INVOKE_TRIGGER_POLL,
};
use std::sync::Arc;
use std::time::Duration;
pub struct FfiTriggerImpl {
handle: Arc<fidius_host::PluginHandle>,
name: String,
poll_interval: Duration,
allow_concurrent: bool,
cron_expression: Option<String>,
}
impl FfiTriggerImpl {
pub fn new(
handle: Arc<fidius_host::PluginHandle>,
name: String,
poll_interval: Duration,
allow_concurrent: bool,
cron_expression: Option<String>,
) -> Self {
Self {
handle,
name,
poll_interval,
allow_concurrent,
cron_expression,
}
}
}
impl std::fmt::Debug for FfiTriggerImpl {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("FfiTriggerImpl")
.field("name", &self.name)
.field("poll_interval", &self.poll_interval)
.field("allow_concurrent", &self.allow_concurrent)
.field("cron_expression", &self.cron_expression)
.finish()
}
}
#[async_trait::async_trait]
impl Trigger for FfiTriggerImpl {
fn name(&self) -> &str {
&self.name
}
fn poll_interval(&self) -> Duration {
self.poll_interval
}
fn allow_concurrent(&self) -> bool {
self.allow_concurrent
}
fn cron_expression(&self) -> Option<String> {
self.cron_expression.clone()
}
async fn poll(&self) -> Result<TriggerResult, TriggerError> {
let handle = self.handle.clone();
let request = TriggerInvokeRequest {
trigger_name: self.name.clone(),
};
let result: Result<TriggerInvokeResult, fidius_host::CallError> =
tokio::task::spawn_blocking(move || {
handle.call_method(METHOD_INVOKE_TRIGGER_POLL, &request)
})
.await
.map_err(|e| TriggerError::PollError {
message: format!("FFI trigger poll spawn_blocking failed: {}", e),
})?;
let r = result.map_err(|e| TriggerError::PollError {
message: format!("FFI trigger poll call failed: {:?}", e),
})?;
if let Some(err) = r.error {
return Err(TriggerError::PollError { message: err });
}
if r.fire {
let ctx = match r.context_json {
Some(json) => {
Some(
Context::from_json(json).map_err(|e| TriggerError::PollError {
message: format!("FFI trigger context parse failed: {}", e),
})?,
)
}
None => None,
};
Ok(TriggerResult::Fire(ctx))
} else {
Ok(TriggerResult::Skip)
}
}
}