use std::collections::HashMap;
use std::sync::Arc;
use crate::TaskId;
use crate::task::RetryPolicy;
use crate::workflow::WorkflowContinuation;
#[derive(Debug, Clone, Default)]
pub struct TaskNodeMetadata {
pub(crate) name: Arc<str>,
pub(crate) timeout: Option<std::time::Duration>,
pub(crate) priority: Option<u8>,
pub(crate) tags: Vec<String>,
pub(crate) retry_policy: Option<RetryPolicy>,
pub(crate) version: Option<String>,
}
impl TaskNodeMetadata {
#[must_use]
pub fn name(&self) -> &Arc<str> {
&self.name
}
#[must_use]
pub fn timeout(&self) -> Option<std::time::Duration> {
self.timeout
}
#[must_use]
pub fn priority(&self) -> Option<u8> {
self.priority
}
#[must_use]
pub fn tags(&self) -> &[String] {
&self.tags
}
#[must_use]
pub fn retry_policy(&self) -> Option<&RetryPolicy> {
self.retry_policy.as_ref()
}
#[must_use]
pub fn version(&self) -> Option<&str> {
self.version.as_deref()
}
}
#[derive(Debug, Clone, Default)]
pub struct TaskIndex(HashMap<TaskId, TaskNodeMetadata>);
impl TaskIndex {
#[must_use]
pub fn build(continuation: &WorkflowContinuation) -> Self {
let map: HashMap<TaskId, TaskNodeMetadata> = continuation
.iter_nodes()
.filter(|n| {
matches!(
n.kind,
crate::workflow::NodeKind::Task
| crate::workflow::NodeKind::Delay
| crate::workflow::NodeKind::AwaitSignal
)
})
.map(|n| {
let metadata = TaskNodeMetadata {
name: Arc::from(n.id),
timeout: n
.timeout
.filter(|_| n.kind == crate::workflow::NodeKind::Task),
priority: n.priority,
tags: n.tags.to_vec(),
retry_policy: n.retry_policy.cloned(),
version: n.version.map(str::to_owned),
};
(TaskId::from(n.id), metadata)
})
.collect();
Self(map)
}
#[must_use]
pub fn contains(&self, task_id: &TaskId) -> bool {
self.0.contains_key(task_id)
}
#[must_use]
pub fn get(&self, task_id: &TaskId) -> Option<&TaskNodeMetadata> {
self.0.get(task_id)
}
#[must_use]
pub fn name(&self, task_id: &TaskId) -> Option<&Arc<str>> {
self.0.get(task_id).map(|m| &m.name)
}
#[must_use]
pub fn priority(&self, task_id: &TaskId) -> Option<u8> {
self.0.get(task_id).and_then(|m| m.priority)
}
#[must_use]
pub fn timeout(&self, task_id: &TaskId) -> Option<std::time::Duration> {
self.0.get(task_id).and_then(|m| m.timeout)
}
#[must_use]
pub fn tags(&self, task_id: &TaskId) -> &[String] {
self.0.get(task_id).map_or(&[], |m| m.tags.as_slice())
}
#[must_use]
pub fn retry_policy(&self, task_id: &TaskId) -> Option<&RetryPolicy> {
self.0.get(task_id).and_then(|m| m.retry_policy.as_ref())
}
#[must_use]
pub fn build_task_metadata(&self, task_id: &TaskId) -> crate::task::TaskMetadata {
match self.0.get(task_id) {
Some(m) => crate::task::TaskMetadata::from_node_fields(
m.timeout,
m.retry_policy.clone(),
m.version.clone(),
m.priority,
m.tags.clone(),
),
None => crate::task::TaskMetadata::default(),
}
}
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}