meerkat_mob/runtime/
spawn_policy.rs1use crate::MobRuntimeMode;
2use crate::ids::{MeerkatId, ProfileName};
3#[cfg(target_arch = "wasm32")]
4use crate::tokio;
5use async_trait::async_trait;
6use std::sync::Arc;
7use tokio::sync::RwLock;
8
9#[derive(Debug, Clone)]
11pub struct SpawnSpec {
12 pub profile: ProfileName,
13 pub runtime_mode: Option<MobRuntimeMode>,
14}
15
16#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
24#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
25pub trait SpawnPolicy: Send + Sync {
26 async fn resolve(&self, target: &MeerkatId) -> Option<SpawnSpec>;
30}
31
32#[derive(Default)]
34pub struct SpawnPolicyService {
35 policy: RwLock<Option<Arc<dyn SpawnPolicy>>>,
36}
37
38impl SpawnPolicyService {
39 pub fn new() -> Self {
40 Self::default()
41 }
42
43 pub async fn set(&self, policy: Option<Arc<dyn SpawnPolicy>>) {
44 *self.policy.write().await = policy;
45 }
46
47 pub async fn resolve(&self, target: &MeerkatId) -> Option<SpawnSpec> {
48 let policy = self.policy.read().await.clone();
49 let policy = policy?;
50 policy.resolve(target).await
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::*;
57
58 struct StaticPolicy;
59
60 #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
61 #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
62 impl SpawnPolicy for StaticPolicy {
63 async fn resolve(&self, target: &MeerkatId) -> Option<SpawnSpec> {
64 Some(SpawnSpec {
65 profile: ProfileName::from(format!("role-{target}")),
66 runtime_mode: Some(MobRuntimeMode::TurnDriven),
67 })
68 }
69 }
70
71 #[tokio::test]
72 async fn spawn_policy_service_swaps_runtime_policy_authority() {
73 let service = SpawnPolicyService::new();
74 let target = MeerkatId::from("worker-1");
75 assert!(service.resolve(&target).await.is_none());
76
77 service.set(Some(Arc::new(StaticPolicy))).await;
78 let resolved = service
79 .resolve(&target)
80 .await
81 .expect("policy should resolve");
82 assert_eq!(resolved.profile, ProfileName::from("role-worker-1"));
83 assert_eq!(resolved.runtime_mode, Some(MobRuntimeMode::TurnDriven));
84 }
85}