1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//! Graph execution middleware.
//!
//! Middleware allows custom logic to be layered around graph execution primitives.
//!
//! In most instances, you will find that the [`hooks`](super::hooks) system will be sufficient
//! for your needs. Middleware is needed when logic must span an execution unit. For example,
//! holding a tracing span guard open for the duration of a system's execution, which is
//! impossible with two disconnected point events.
//!
//! # Targets
//!
//! Each target type determines which execution unit a middleware wraps. Register
//! middleware using the corresponding `register_*` method on [`MiddlewareAPI`].
//!
//! | Target | Info type | Scope |
//! |--------|-----------|-------|
//! | [`GraphExecution`] | [`GraphInfo`] | Entire graph run |
//! | [`System`] | [`SystemInfo`] | Single system node |
//! | [`Loop`] | [`LoopInfo`] | Entire loop node |
//! | [`Parallel`] | [`ParallelInfo`] | Entire parallel node |
//! | [`Decision`] | [`DecisionInfo`] | Decision node evaluation |
//! | [`Switch`] | [`SwitchInfo`] | Switch node evaluation |
//! | [`LoopIteration`] | [`LoopIterationInfo`] | Single loop iteration |
//! | [`ParallelBranch`] | [`ParallelBranchInfo`] | Single parallel branch |
//! | [`Scope`] | [`ScopeInfo`] | Scope node execution |
//!
//! # Layer Ordering
//!
//! Multiple middlewares can be registered on the same target. Each layer wraps
//! the next, forming a chain that runs inward until it reaches the terminal,
//! consisting in the actual execution logic for the target (e.g. running a system node).
//! The last registered middleware is the outermost layer. Hooks execute after
//! all the middleware layers.
//!
//! If A is registered before B, execution flows:
//! B → A → hooks → terminal → hooks → A → B.
//!
//! # Handlers
//!
//! A handler (see [`MiddlewareHandler`]) receives three arguments:
//!
//! - `info` — typed metadata about the execution unit (e.g. [`SystemInfo`]).
//! - `ctx` — exclusive `&mut` access to the [`SystemContext`](polaris_system::param::SystemContext).
//! - `next` — a [`Next`] value representing the rest of the chain. Call
//! [`Next::run`] to continue inward. Code before the call runs on the way
//! in, code after runs on the way out. Every handler must call
//! [`Next::run`] exactly once; dropping `next` without invoking it
//! (short-circuiting) is not permitted and will produce an
//! [`ExecutionError::InternalError`].
//!
//! # Example
//!
//! ```
//! # use polaris_graph::middleware::{MiddlewareAPI, info::SystemInfo};
//! # let mw = MiddlewareAPI::new();
//! mw.register_system("logger", |info: SystemInfo, ctx, next| {
//! Box::pin(async move {
//! tracing::info!("before system: {}", info.node_name);
//! let result = next.run(ctx).await;
//! tracing::info!("after system: {}", info.node_name);
//! result
//! })
//! });
//! ```
pub use ;
// ─────────────────────────────────────────────────────────────────────────────
// Top-level targets
// ─────────────────────────────────────────────────────────────────────────────
/// Middleware target for the entire graph execution. See [`GraphInfo`].
;
// ─────────────────────────────────────────────────────────────────────────────
// Node-level targets
// ─────────────────────────────────────────────────────────────────────────────
/// Middleware target for system node execution. See [`SystemInfo`].
;
/// Middleware target for the loop node as a whole, spanning every iteration
/// from entry to termination. For per-iteration middleware, see [`LoopIteration`].
///
/// See [`LoopInfo`] for the metadata available to this middleware.
;
/// Middleware target for the parallel node as a whole, spanning from the initial
/// fan-out through all branches to the final join. For per-branch middleware, see
/// [`ParallelBranch`].
///
/// See [`ParallelInfo`] for the metadata available to this middleware.
;
/// Middleware target for decision node evaluation. See [`DecisionInfo`].
;
/// Middleware target for switch node evaluation. See [`SwitchInfo`].
;
/// Middleware target for scope node execution. See [`ScopeInfo`].
;
// ─────────────────────────────────────────────────────────────────────────────
// Sub-node-level targets
// ─────────────────────────────────────────────────────────────────────────────
/// Middleware target for a single loop iteration. See [`LoopIterationInfo`].
;
/// Middleware target for a single parallel branch. See [`ParallelBranchInfo`].
;