Skip to main content

noetl_executor/
runtime.rs

1//! Per-execution runtime context shared between sources, dispatch, and
2//! event emission.
3//!
4//! `ExecutionContext` is the durable carrier for one playbook execution.
5//! Both the CLI's local-mode runner and the worker's NATS daemon
6//! construct one of these per invocation; the dispatch layer reads from
7//! it to resolve credentials, look up rendered step input, and emit
8//! events into the configured sink.
9//!
10//! This module deliberately starts minimal — the skeleton commits the
11//! shape, R-1.2 (extraction PR) fills in the concrete fields by porting
12//! them from `repos/cli/src/playbook_runner.rs`.
13
14use anyhow::Result;
15use std::collections::HashMap;
16use std::sync::Arc;
17
18/// Identifies one playbook execution end-to-end.
19#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
20pub struct ExecutionId(pub String);
21
22/// Trait for resolving keychain credential aliases at step-execution
23/// time.  Mirrors the Python-side `noetl.core.credential_refs`
24/// resolution flow; see noetl/noetl wiki page `credential-resolution-flow`.
25#[async_trait::async_trait]
26pub trait CredentialResolver: Send + Sync {
27    /// Resolve `alias` (e.g. `"duffel"`) to its concrete credential
28    /// envelope.  Implementations consult the NoETL keychain (worker
29    /// path) or the CLI's local keychain cache (CLI path).
30    async fn resolve(&self, alias: &str) -> Result<serde_json::Value>;
31}
32
33/// Carries everything one execution needs.  Cheap to clone via `Arc`s
34/// on the inner heavy fields.
35#[derive(Clone)]
36pub struct ExecutionContext {
37    pub execution_id: ExecutionId,
38    pub credentials: Arc<dyn CredentialResolver>,
39    /// Step-level results accumulated during execution.  Used by the
40    /// template layer to render `{{ step_name.result }}` references.
41    pub step_results: Arc<tokio::sync::RwLock<HashMap<String, serde_json::Value>>>,
42    /// Workload payload (`workload:` block from the YAML, plus any
43    /// `--set` overrides from the CLI or runtime defaults from NATS).
44    pub workload: Arc<serde_json::Value>,
45}
46
47impl ExecutionContext {
48    /// Construct a fresh context.  R-1.2 will add a builder that
49    /// reads the workload from the YAML's `workload:` block and
50    /// applies CLI overrides.
51    pub fn new(
52        execution_id: ExecutionId,
53        credentials: Arc<dyn CredentialResolver>,
54        workload: serde_json::Value,
55    ) -> Self {
56        Self {
57            execution_id,
58            credentials,
59            step_results: Arc::new(tokio::sync::RwLock::new(HashMap::new())),
60            workload: Arc::new(workload),
61        }
62    }
63}