bamboo_engine/
session_repository_parent_outcome.rs1use super::*;
6use bamboo_domain::{
7 ActorActivationFinish, ActorActivationStatus, RootActorExecutionBinding,
8 RuntimeSessionPersistence,
9};
10
11pub struct ParentOutcomeRoute {
12 directory: Option<std::sync::Weak<dyn bamboo_domain::ActorDirectoryPort>>,
13 writers: std::sync::Weak<
14 dashmap::DashMap<String, std::sync::Weak<bamboo_domain::RootActorRuntimeWrite>>,
15 >,
16}
17
18impl ParentOutcomeRoute {
19 pub fn rebind(&self, mut repository: SessionRepository) -> Option<SessionRepository> {
22 if let Some(directory) = &self.directory {
23 repository.root_actor_directory = Some(directory.upgrade()?);
24 repository.root_actor_writers = self.writers.upgrade()?;
25 }
26 Some(repository)
27 }
28}
29
30pub struct ParentOutcomeWriter {
31 repository: SessionRepository,
32 execution: Option<RootActorExecutionBinding>,
33}
34
35impl ParentOutcomeWriter {
36 pub fn repository(&self) -> &SessionRepository {
37 &self.repository
38 }
39
40 pub async fn finish(mut self) -> std::io::Result<()> {
43 let Some(mut execution) = self.execution.take() else {
44 return Ok(());
45 };
46 execution
47 .directory
48 .finish_activation(
49 &execution.owner.fence,
50 chrono::Utc::now(),
51 ActorActivationFinish::Succeeded,
52 )
53 .await
54 .map_err(root_actor_binding_error)?;
55 execution.disarm_abandonment();
56 Ok(())
57 }
58}
59
60impl SessionRepository {
61 pub fn downgrade_parent_outcome_route(&self) -> ParentOutcomeRoute {
62 ParentOutcomeRoute {
63 directory: self.root_actor_directory.as_ref().map(Arc::downgrade),
64 writers: Arc::downgrade(&self.root_actor_writers),
65 }
66 }
67 pub async fn bind_parent_outcome_writer(
71 &self,
72 session_id: &str,
73 ) -> std::io::Result<ParentOutcomeWriter> {
74 let session = self
75 .storage
76 .load_session(session_id)
77 .await?
78 .ok_or_else(|| root_actor_binding_error("Parent outcome target is missing"))?;
79 if let Some((_, owner)) = &self.root_actor_owner {
80 if owner.fence.actor_id != session_id || owner.created_at != session.created_at {
81 return Err(root_actor_binding_error(
82 "Parent outcome execution target changed",
83 ));
84 }
85 return Ok(ParentOutcomeWriter {
86 repository: self.clone(),
87 execution: None,
88 });
89 }
90 if !self.root_actor_execution_required(&session) {
91 return Ok(ParentOutcomeWriter {
92 repository: self.clone(),
93 execution: None,
94 });
95 }
96 if let Some(origin) = bamboo_agent_core::tools::context::root_actor_tool_writer() {
97 let owner = origin.ok_or_else(|| {
98 root_actor_binding_error("Parent reply has no Root execution capability")
99 })?;
100 if owner.fence.actor_id != session_id || owner.created_at != session.created_at {
101 return Err(root_actor_binding_error(
102 "Parent reply execution target changed",
103 ));
104 }
105 return Ok(ParentOutcomeWriter {
106 repository: self.bind_root_response_writer(owner)?,
107 execution: None,
108 });
109 }
110 let directory = self.root_actor_directory.as_ref().ok_or_else(|| {
111 root_actor_binding_error("Parent outcome requires its Host Actor directory")
112 })?;
113 let active_owner = self
114 .root_actor_writers
115 .get(session_id)
116 .and_then(|entry| entry.value().upgrade());
117 if let Some(owner) = active_owner {
118 let current = directory
119 .inspect_actor(session_id)
120 .await
121 .map_err(root_actor_binding_error)?;
122 if current.activation.is_some_and(|activation| {
123 activation.fence() == owner.fence
124 && activation.status == ActorActivationStatus::Running
125 && activation.lease_expires_at > chrono::Utc::now()
126 }) {
127 return Ok(ParentOutcomeWriter {
130 repository: self.bind_root_response_writer((*owner).clone())?,
131 execution: None,
132 });
133 }
134 }
135 let execution = self
139 .bind_root_actor_execution(
140 &session,
141 &format!("parent-outcome-{}", uuid::Uuid::new_v4()),
142 )
143 .await?
144 .ok_or_else(|| root_actor_binding_error("Parent outcome Root binding is absent"))?;
145 let repository = self.bind_root_response_writer(execution.owner.clone())?;
146 Ok(ParentOutcomeWriter {
147 repository,
148 execution: Some(execution),
149 })
150 }
151}