Skip to main content

palladium_runtime/engine/
config.rs

1use std::collections::{BTreeSet, HashMap};
2use std::path::PathBuf;
3use std::sync::Arc;
4use std::time::Duration;
5
6use palladium_actor::{ActorPath, EngineId};
7use palladium_federation::{
8    ClusterMembership, ConsensusEngine, FederatedRegistry, FederationPolicy, MembershipConfig,
9};
10use palladium_transport::TlsConfig;
11use parking_lot::RwLock;
12
13#[derive(Clone, Debug, Default)]
14pub struct ConsensusGroupMeta {
15    pub members: BTreeSet<EngineId>,
16}
17
18#[derive(Clone, Debug)]
19pub struct ConsensusEngineInfo {
20    pub kind: String,
21    pub engine_id: EngineId,
22    pub tcp_addr: String,
23    pub quic_addr: Option<String>,
24    pub prefer_quic: bool,
25    pub tls_enabled: bool,
26}
27
28use crate::control_plane::PluginRpcHandler;
29use crate::reactor::Reactor;
30use crate::supervisor::{RestartIntensity, SupervisionStrategy};
31
32pub type ActorSpawnFn<R> =
33    dyn Fn(&str, &[u8]) -> Result<Box<dyn palladium_actor::Actor<R>>, String> + Send + Sync;
34
35/// Configuration for `Engine`.
36#[derive(Clone)]
37pub struct EngineConfig<R: Reactor> {
38    /// Supervision strategy for the `/user` root supervisor.
39    pub user_strategy: SupervisionStrategy,
40    /// Supervision strategy for the `/system` root supervisor.
41    pub system_strategy: SupervisionStrategy,
42    /// Restart intensity for root supervisors.
43    pub intensity: RestartIntensity,
44    /// Shutdown timeout before escalating to `Brutal` force-kill.
45    pub shutdown_timeout: Duration,
46    /// Default ask timeout for `Addr<M>::ask()`.
47    pub ask_timeout: Duration,
48    /// Maximum number of pending ask requests (REQ-072).
49    pub response_capacity: usize,
50    /// Unix socket path for the control plane server (REQ-086).
51    ///
52    /// `None` disables the control plane. When set, the engine spawns a
53    /// `ControlPlaneActor` at `/system/control-plane` that listens for
54    /// JSON-RPC 2.0 requests on this socket.
55    pub control_plane_socket: Option<PathBuf>,
56    /// Identity of this engine. Required for network transport.
57    pub engine_id: EngineId,
58    /// TCP listener address for the control plane (Phase 6, stub).
59    pub control_plane_tcp_addr: Option<String>,
60    /// QUIC listener address for the control plane (Phase 6, stub).
61    pub control_plane_quic_addr: Option<String>,
62    /// TLS configuration for network control plane endpoints (mTLS required).
63    pub control_plane_tls: Option<TlsConfig>,
64    /// Number of cores for [`MultiCoreEngine`].
65    ///
66    /// `None` defaults to the number of available logical CPUs.
67    pub num_cores: Option<usize>,
68    /// Capacity of each inter-core ring buffer (messages). Defaults to 4096.
69    pub inter_core_queue_capacity: usize,
70    /// Optional plugin management handler for `plugin.*` control-plane RPCs.
71    ///
72    /// When `None` (the default), `plugin.*` methods return a "not implemented"
73    /// error. Wire in a `PluginRegistry`-backed implementation to enable live
74    /// plugin management via the CLI.
75    pub plugin_rpc: Option<Arc<dyn PluginRpcHandler<R>>>,
76    /// Optional built-in actor spawn handler (non-plugin types).
77    pub actor_spawn: Option<Arc<ActorSpawnFn<R>>>,
78    /// Optional cluster membership state for federation-aware control plane RPCs.
79    ///
80    /// When set, `cluster.status` and `cluster.members` return data from this
81    /// shared membership view. When `None`, those RPCs return a "not enabled" error.
82    pub cluster_membership: Option<Arc<RwLock<ClusterMembership>>>,
83    /// Enable built-in federation gossip service.
84    pub federation_enabled: bool,
85    /// Bind address for federation gossip (host:port).
86    pub federation_bind_addr: Option<String>,
87    /// Seed node addresses for federation gossip.
88    pub federation_seed_nodes: Vec<String>,
89    /// Federation membership config (gossip interval, timeouts, fanout).
90    pub federation_membership: MembershipConfig,
91    /// Federation routing policy (used by FederatedRouting).
92    pub federation_policy: FederationPolicy,
93    /// Shared federated registry for gossip and routing.
94    pub federated_registry: Option<Arc<RwLock<FederatedRegistry>>>,
95    /// Consensus engine for group management (Phase 8.3).
96    pub consensus_engine: Option<Arc<dyn ConsensusEngine>>,
97    /// Actor path → consensus group mapping.
98    pub consensus_groups: Option<Arc<RwLock<HashMap<ActorPath, String>>>>,
99    /// Consensus group metadata (members, etc.).
100    pub consensus_group_meta: Option<Arc<RwLock<HashMap<String, ConsensusGroupMeta>>>>,
101    /// Consensus engine configuration summary (for CLI visibility).
102    pub consensus_engine_info: Option<ConsensusEngineInfo>,
103    /// WASM determinism enforcement level.
104    pub determinism_level: palladium_actor::DeterminismLevel,
105}
106
107impl<R: Reactor> std::fmt::Debug for EngineConfig<R> {
108    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
109        f.debug_struct("EngineConfig")
110            .field("user_strategy", &self.user_strategy)
111            .field("system_strategy", &self.system_strategy)
112            .field("intensity", &self.intensity)
113            .field("shutdown_timeout", &self.shutdown_timeout)
114            .field("ask_timeout", &self.ask_timeout)
115            .field("response_capacity", &self.response_capacity)
116            .field("control_plane_socket", &self.control_plane_socket)
117            .field("engine_id", &self.engine_id)
118            .field("control_plane_tcp_addr", &self.control_plane_tcp_addr)
119            .field("control_plane_quic_addr", &self.control_plane_quic_addr)
120            .field(
121                "control_plane_tls",
122                &self.control_plane_tls.as_ref().map(|_| "<TlsConfig>"),
123            )
124            .field("num_cores", &self.num_cores)
125            .field("inter_core_queue_capacity", &self.inter_core_queue_capacity)
126            .field(
127                "plugin_rpc",
128                &self.plugin_rpc.as_ref().map(|_| "<PluginRpcHandler>"),
129            )
130            .field(
131                "actor_spawn",
132                &self.actor_spawn.as_ref().map(|_| "<ActorSpawnFn>"),
133            )
134            .field(
135                "cluster_membership",
136                &self
137                    .cluster_membership
138                    .as_ref()
139                    .map(|_| "<ClusterMembership>"),
140            )
141            .field("federation_enabled", &self.federation_enabled)
142            .field("federation_bind_addr", &self.federation_bind_addr)
143            .field("federation_seed_nodes", &self.federation_seed_nodes)
144            .field("federation_membership", &self.federation_membership)
145            .field("federation_policy", &self.federation_policy)
146            .field(
147                "federated_registry",
148                &self
149                    .federated_registry
150                    .as_ref()
151                    .map(|_| "<FederatedRegistry>"),
152            )
153            .field(
154                "consensus_engine",
155                &self.consensus_engine.as_ref().map(|_| "<ConsensusEngine>"),
156            )
157            .field(
158                "consensus_groups",
159                &self.consensus_groups.as_ref().map(|_| "<ConsensusGroups>"),
160            )
161            .field(
162                "consensus_group_meta",
163                &self
164                    .consensus_group_meta
165                    .as_ref()
166                    .map(|_| "<ConsensusGroupMeta>"),
167            )
168            .field(
169                "consensus_engine_info",
170                &self
171                    .consensus_engine_info
172                    .as_ref()
173                    .map(|_| "<ConsensusEngineInfo>"),
174            )
175            .field("determinism_level", &self.determinism_level)
176            .finish()
177    }
178}
179
180impl<R: Reactor> Default for EngineConfig<R> {
181    fn default() -> Self {
182        Self {
183            user_strategy: SupervisionStrategy::OneForOne,
184            system_strategy: SupervisionStrategy::OneForOne,
185            intensity: RestartIntensity::default(),
186            shutdown_timeout: Duration::from_secs(30),
187            ask_timeout: Duration::from_secs(5),
188            response_capacity: 10000,
189            control_plane_socket: None,
190            engine_id: EngineId::new("engine-default"),
191            control_plane_tcp_addr: None,
192            control_plane_quic_addr: None,
193            control_plane_tls: None,
194            num_cores: None,
195            inter_core_queue_capacity: 4096,
196            plugin_rpc: None,
197            actor_spawn: None,
198            cluster_membership: None,
199            federation_enabled: false,
200            federation_bind_addr: None,
201            federation_seed_nodes: Vec::new(),
202            federation_membership: MembershipConfig::default(),
203            federation_policy: FederationPolicy::AllowAll,
204            federated_registry: None,
205            consensus_engine: None,
206            consensus_groups: None,
207            consensus_group_meta: None,
208            consensus_engine_info: None,
209            determinism_level: palladium_actor::DeterminismLevel::Strict,
210        }
211    }
212}