harmos_runtime/operations/manager/
registration.rs1use super::*;
22
23impl OperationManager {
38 pub fn register_operation<T>(&self, owner: impl Into<String>, lane: impl Lane, resources: Arc<T::Resources>) -> Result<()>
39 where
40 T: for<'ctx> crate::operations::Operation<Context<'ctx> = Context<'ctx>>,
41 {
42 self.register_operation_at::<T>(owner, lane.name(), resources)
43 }
44
45 pub fn register_operation_id<T>(
46 &self, owner: impl Into<String>, id: impl Into<String>, lane: impl Lane, resources: Arc<T::Resources>,
47 ) -> Result<()>
48 where
49 T: for<'ctx> crate::operations::Operation<Context<'ctx> = Context<'ctx>>,
50 {
51 self.register_with(owner, |bindings| bindings.register_operation_id::<T>(id, lane, resources))
52 }
53
54 pub(in crate::operations) fn register_operation_at<T>(
55 &self, owner: impl Into<String>, lane: &'static str, resources: Arc<T::Resources>,
56 ) -> Result<()>
57 where
58 T: for<'ctx> crate::operations::Operation<Context<'ctx> = Context<'ctx>>,
59 {
60 self.register_with(owner, |bindings| bindings.register_owned_at::<T>(lane, resources))
61 }
62
63 pub fn register_wire_operation<T>(&self, owner: impl Into<String>, lane: impl Lane, resources: Arc<T::Resources>) -> Result<()>
64 where
65 T: for<'ctx> crate::operations::Operation<Context<'ctx> = Context<'ctx>>,
66 {
67 self.register_with(owner, |bindings| bindings.register_wire_operation::<T>(lane, resources))
68 }
69
70 pub fn register_wire_contract<T>(
71 &self, owner: impl Into<String>, contract: &crate::operations::Contract, lane: impl Lane, resources: Arc<T::Resources>,
72 ) -> Result<()>
73 where
74 T: for<'ctx> crate::operations::Operation<Context<'ctx> = Context<'ctx>>,
75 {
76 self.register_with(owner, |bindings| bindings.register_wire_contract::<T>(contract, lane, resources))
77 }
78
79 pub(in crate::operations) fn binding_owned_definition<T>(
80 &self, owner: impl Into<String>, lane: &'static str, resources: Arc<T::Resources>, definition: Definition,
81 wire: Option<crate::operations::wire::Dispatch>,
82 #[cfg(any(feature = "plugin", feature = "plugin-guest", feature = "plugin-sidecar"))] plugin: Option<PluginScope>,
83 ) -> Result<Arc<Entry>>
84 where
85 T: for<'ctx> crate::operations::Operation<Context<'ctx> = Context<'ctx>>,
86 {
87 #[cfg(feature = "plugin-sidecar")]
89 let built_in = plugin.as_ref().and_then(PluginScope::observe_contract).is_some_and(|contract| *contract.operation() == definition);
90 #[cfg(not(feature = "plugin-sidecar"))]
91 let built_in = false;
92 if built_in { definition.policy.validate().map_err(harmos_domain::Error::from) } else { definition.validate() }
93 .map_err(|source| Error::OperationDeclaration { source })?;
94 if <T::Endpoints as crate::operations::EndpointSet>::item_types() != crate::operations::item_types::<T::Declaration>() {
95 return Err(Error::InvalidInput {
96 field: "operation endpoint types",
97 reason: "authored endpoints do not match declared stream item types",
98 });
99 }
100 let binding = crate::operations::authored::factory::<T>(self, resources);
101 self.binding_typed(
102 owner,
103 lane,
104 binding,
105 definition,
106 wire,
107 #[cfg(any(feature = "plugin", feature = "plugin-guest", feature = "plugin-sidecar"))]
108 plugin,
109 )
110 }
111
112 pub(super) fn binding_typed<O: OperationDeclaration, P: Send + 'static>(
113 &self, owner: impl Into<String>, lane: &'static str, binding: Typed<O, P>, definition: Definition,
114 wire: Option<crate::operations::wire::Dispatch>,
115 #[cfg(any(feature = "plugin", feature = "plugin-guest", feature = "plugin-sidecar"))] plugin: Option<PluginScope>,
116 ) -> Result<Arc<Entry>> {
117 let owner = Identifier::new(owner.into()).map_err(|source| Error::OperationDeclaration { source: source.into() })?;
118 let bounded =
119 self.instances.lane_bounded(lane).ok_or_else(|| Error::NotRegistered { domain: "operation lane", name: lane.to_owned() })?;
120 let generation = OperationGeneration::fresh()?;
121 Ok(Arc::new(Entry {
122 owner,
123 definition,
124 contract: None,
125 #[cfg(feature = "grpc")]
126 grpc: None,
127 generation,
128 lane,
129 bounded,
130 #[cfg(feature = "plugin-sidecar")]
131 resident: false,
132 active: AtomicBool::new(true),
133 retirement: AtomicU8::new(Retirement::Retained as u8),
134 pending: Mutex::new(BTreeMap::new()),
135 binding: Arc::new(binding),
136 #[cfg(feature = "plugin-sidecar")]
137 native_binding: None,
138 wire,
139 #[cfg(feature = "plugin-sidecar")]
140 native: None,
141 #[cfg(any(feature = "plugin", feature = "plugin-guest", feature = "plugin-sidecar"))]
142 plugin,
143 #[cfg(any(feature = "plugin", feature = "plugin-guest", feature = "plugin-sidecar"))]
144 sdk: None,
145 }))
146 }
147}
148
149