routing/
component_instance.rs1use crate::bedrock::sandbox_construction::ComponentSandbox;
6use crate::error::ComponentInstanceError;
7use crate::policy::GlobalPolicyChecker;
8use crate::resolving::{ComponentAddress, ComponentResolutionContext, ResolverError};
9use async_trait::async_trait;
10use capability_source::{BuiltinCapabilities, NamespaceCapabilities};
11use cm_types::Url;
12use derivative::Derivative;
13use moniker::{BorrowedChildName, ExtendedMoniker, Moniker};
14use runtime_capabilities::{WeakInstanceToken, WeakInstanceTokenAny};
15use std::clone::Clone;
16use std::sync::{Arc, Weak};
17
18#[async_trait]
20pub trait ComponentInstanceInterface: Sized + Send + Sync {
21 type TopInstance: TopInstanceInterface + Send + Sync;
22
23 fn as_weak(self: &Arc<Self>) -> WeakComponentInstanceInterface<Self> {
25 WeakComponentInstanceInterface::new(self)
26 }
27
28 fn child_moniker(&self) -> Option<&BorrowedChildName> {
31 self.moniker().leaf()
32 }
33
34 fn moniker(&self) -> &Moniker;
36
37 fn url(&self) -> &Url;
39
40 fn config_parent_overrides(&self) -> Option<&[cm_rust::ConfigOverride]>;
42
43 fn policy_checker(&self) -> &GlobalPolicyChecker;
45
46 fn component_id_index(&self) -> &component_id_index::Index;
48
49 fn try_get_parent(&self) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError>;
51
52 async fn component_sandbox(
54 self: &Arc<Self>,
55 ) -> Result<ComponentSandbox, ComponentInstanceError>;
56
57 async fn get_child_maybe_resolve(
59 self: &Arc<Self>,
60 moniker: &BorrowedChildName,
61 ) -> Result<Option<Arc<Self>>, ComponentInstanceError>;
62
63 async fn address_maybe_resolve(self: &Arc<Self>) -> Result<ComponentAddress, ResolverError>;
67
68 async fn context_to_resolve_children(
73 self: &Arc<Self>,
74 ) -> Result<Option<ComponentResolutionContext>, ComponentInstanceError>;
75
76 async fn find_extended_instance(
81 self: &Arc<Self>,
82 moniker: &ExtendedMoniker,
83 ) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError> {
84 match moniker {
85 ExtendedMoniker::ComponentInstance(moniker) => {
86 Ok(ExtendedInstanceInterface::Component(self.find_absolute(moniker).await?))
87 }
88 ExtendedMoniker::ComponentManager => {
89 Ok(ExtendedInstanceInterface::AboveRoot(self.find_above_root()?))
90 }
91 }
92 }
93
94 async fn find_absolute(
98 self: &Arc<Self>,
99 target_moniker: &Moniker,
100 ) -> Result<Arc<Self>, ComponentInstanceError> {
101 let mut current = self.clone();
102 while !target_moniker.has_prefix(current.moniker()) {
103 match current.try_get_parent()? {
104 ExtendedInstanceInterface::AboveRoot(_) => panic!(
105 "the current component ({}) must be root, but it's not a prefix for {}",
106 current.moniker(),
107 target_moniker
108 ),
109 ExtendedInstanceInterface::Component(parent) => current = parent,
110 }
111 }
112 while current.moniker() != target_moniker {
113 let remaining_path = target_moniker.strip_prefix(current.moniker()).expect(
114 "previous loop will only exit when current.moniker() is a prefix of target_moniker",
115 );
116 for moniker_part in remaining_path.path() {
117 let child = current.get_child_maybe_resolve(moniker_part).await?.ok_or(
118 ComponentInstanceError::InstanceNotFound {
119 moniker: current.moniker().child(moniker_part.into()),
120 },
121 )?;
122 current = child;
123 }
124 }
125 Ok(current)
126 }
127
128 fn find_above_root(self: &Arc<Self>) -> Result<Arc<Self::TopInstance>, ComponentInstanceError> {
131 let mut current = self.clone();
132 loop {
133 match current.try_get_parent()? {
134 ExtendedInstanceInterface::AboveRoot(top_instance) => return Ok(top_instance),
135 ExtendedInstanceInterface::Component(parent) => current = parent,
136 }
137 }
138 }
139}
140
141#[derive(Derivative)]
145#[derivative(Clone(bound = ""), Default(bound = ""), Debug)]
146pub struct WeakComponentInstanceInterface<C: ComponentInstanceInterface> {
147 #[derivative(Debug = "ignore")]
148 inner: Weak<C>,
149 pub moniker: Moniker,
150}
151
152impl<C: ComponentInstanceInterface> WeakComponentInstanceInterface<C> {
153 pub fn new(component: &Arc<C>) -> Self {
154 Self { inner: Arc::downgrade(component), moniker: component.moniker().clone() }
155 }
156
157 pub fn invalid() -> Self {
159 Self { inner: Weak::new(), moniker: Moniker::new(&[]) }
160 }
161
162 pub fn upgrade(&self) -> Result<Arc<C>, ComponentInstanceError> {
165 self.inner
166 .upgrade()
167 .ok_or_else(|| ComponentInstanceError::instance_not_found(self.moniker.clone()))
168 }
169}
170
171impl<C: ComponentInstanceInterface> From<&Arc<C>> for WeakComponentInstanceInterface<C> {
172 fn from(component: &Arc<C>) -> Self {
173 Self { inner: Arc::downgrade(component), moniker: component.moniker().clone() }
174 }
175}
176
177impl<C: ComponentInstanceInterface + 'static> TryFrom<Arc<WeakInstanceToken>>
178 for WeakComponentInstanceInterface<C>
179{
180 type Error = ();
181
182 fn try_from(
183 weak_component_token: Arc<WeakInstanceToken>,
184 ) -> Result<WeakComponentInstanceInterface<C>, Self::Error> {
185 let weak_extended: WeakExtendedInstanceInterface<C> = weak_component_token.try_into()?;
186 match weak_extended {
187 WeakExtendedInstanceInterface::Component(weak_component) => Ok(weak_component),
188 WeakExtendedInstanceInterface::AboveRoot(_) => Err(()),
189 }
190 }
191}
192
193impl<C: ComponentInstanceInterface + 'static> PartialEq for WeakComponentInstanceInterface<C> {
194 fn eq(&self, other: &Self) -> bool {
195 self.inner.ptr_eq(&other.inner) && self.moniker == other.moniker
196 }
197}
198
199#[derive(Debug, Clone)]
201pub enum ExtendedInstanceInterface<C: ComponentInstanceInterface> {
202 Component(Arc<C>),
203 AboveRoot(Arc<C::TopInstance>),
204}
205
206#[derive(Derivative)]
208#[derivative(Clone(bound = ""), Debug(bound = ""))]
209pub enum WeakExtendedInstanceInterface<C: ComponentInstanceInterface> {
210 Component(WeakComponentInstanceInterface<C>),
211 AboveRoot(Weak<C::TopInstance>),
212}
213
214impl<C: ComponentInstanceInterface + 'static> WeakInstanceTokenAny
215 for WeakExtendedInstanceInterface<C>
216{
217 fn as_any(&self) -> &dyn std::any::Any {
218 self
219 }
220}
221
222impl<C: ComponentInstanceInterface> WeakExtendedInstanceInterface<C> {
223 pub fn upgrade(&self) -> Result<ExtendedInstanceInterface<C>, ComponentInstanceError> {
226 match self {
227 WeakExtendedInstanceInterface::Component(p) => {
228 Ok(ExtendedInstanceInterface::Component(p.upgrade()?))
229 }
230 WeakExtendedInstanceInterface::AboveRoot(p) => {
231 Ok(ExtendedInstanceInterface::AboveRoot(
232 p.upgrade().ok_or_else(ComponentInstanceError::cm_instance_unavailable)?,
233 ))
234 }
235 }
236 }
237
238 pub fn extended_moniker(&self) -> ExtendedMoniker {
239 match self {
240 Self::Component(p) => ExtendedMoniker::ComponentInstance(p.moniker.clone()),
241 Self::AboveRoot(_) => ExtendedMoniker::ComponentManager,
242 }
243 }
244}
245
246impl<C: ComponentInstanceInterface> From<&ExtendedInstanceInterface<C>>
247 for WeakExtendedInstanceInterface<C>
248{
249 fn from(extended: &ExtendedInstanceInterface<C>) -> Self {
250 match extended {
251 ExtendedInstanceInterface::Component(component) => {
252 WeakExtendedInstanceInterface::Component(WeakComponentInstanceInterface::new(
253 component,
254 ))
255 }
256 ExtendedInstanceInterface::AboveRoot(top_instance) => {
257 WeakExtendedInstanceInterface::AboveRoot(Arc::downgrade(top_instance))
258 }
259 }
260 }
261}
262
263impl<C: ComponentInstanceInterface + 'static> TryFrom<Arc<WeakInstanceToken>>
264 for WeakExtendedInstanceInterface<C>
265{
266 type Error = ();
267
268 fn try_from(
269 weak_component_token: Arc<WeakInstanceToken>,
270 ) -> Result<WeakExtendedInstanceInterface<C>, Self::Error> {
271 weak_component_token
272 .inner
273 .as_any()
274 .downcast_ref::<WeakExtendedInstanceInterface<C>>()
275 .cloned()
276 .ok_or(())
277 }
278}
279
280pub trait TopInstanceInterface: Sized + std::fmt::Debug {
282 fn namespace_capabilities(&self) -> &NamespaceCapabilities;
283
284 fn builtin_capabilities(&self) -> &BuiltinCapabilities;
285}
286
287#[cfg(test)]
288pub mod tests {
289 use super::*;
290 use crate::bedrock::sandbox_construction::ComponentSandbox;
291
292 #[derive(Debug)]
293 pub struct TestTopInstance {}
294
295 impl TopInstanceInterface for TestTopInstance {
296 fn namespace_capabilities(&self) -> &NamespaceCapabilities {
297 todo!()
298 }
299
300 fn builtin_capabilities(&self) -> &BuiltinCapabilities {
301 todo!()
302 }
303 }
304
305 pub struct TestComponent {}
306
307 #[async_trait]
308 impl ComponentInstanceInterface for TestComponent {
309 type TopInstance = TestTopInstance;
310
311 fn child_moniker(&self) -> Option<&BorrowedChildName> {
312 todo!()
313 }
314
315 fn moniker(&self) -> &Moniker {
316 todo!()
317 }
318
319 fn url(&self) -> &Url {
320 todo!()
321 }
322
323 fn config_parent_overrides(&self) -> Option<&[cm_rust::ConfigOverride]> {
324 todo!()
325 }
326
327 fn policy_checker(&self) -> &GlobalPolicyChecker {
328 todo!()
329 }
330
331 fn component_id_index(&self) -> &component_id_index::Index {
332 todo!()
333 }
334
335 fn try_get_parent(
336 &self,
337 ) -> Result<ExtendedInstanceInterface<Self>, ComponentInstanceError> {
338 todo!()
339 }
340
341 async fn component_sandbox(
342 self: &Arc<Self>,
343 ) -> Result<ComponentSandbox, ComponentInstanceError> {
344 todo!()
345 }
346
347 async fn get_child_maybe_resolve(
348 self: &Arc<Self>,
349 _moniker: &BorrowedChildName,
350 ) -> Result<Option<Arc<Self>>, ComponentInstanceError> {
351 todo!()
352 }
353
354 async fn address_maybe_resolve(
355 self: &Arc<Self>,
356 ) -> Result<ComponentAddress, ResolverError> {
357 todo!()
358 }
359
360 async fn context_to_resolve_children(
361 self: &Arc<Self>,
362 ) -> Result<Option<ComponentResolutionContext>, ComponentInstanceError> {
363 todo!()
364 }
365 }
366}