Skip to main content

Mountain/RunTime/Execute/
Run.rs

1
2//! `ApplicationRunTimeTrait::Run` - submit an `ActionEffect` to the Echo
3//! work-stealing scheduler and block on the oneshot reply.
4
5use std::sync::Arc;
6
7use CommonLibrary::{
8	Effect::{ActionEffect::ActionEffect, ApplicationRunTime::ApplicationRunTime as ApplicationRunTimeTrait},
9	Environment::Requires::Requires,
10	Error::CommonError::CommonError,
11};
12use Echo::Task::Priority::Priority;
13use async_trait::async_trait;
14
15use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
16
17#[async_trait]
18impl ApplicationRunTimeTrait for ApplicationRunTime {
19	async fn Run<TCapabilityProvider, TError, TOutput>(
20		&self,
21
22		Effect:ActionEffect<Arc<TCapabilityProvider>, TError, TOutput>,
23	) -> Result<TOutput, TError>
24	where
25		TCapabilityProvider: ?Sized + Send + Sync + 'static,
26		<Self as CommonLibrary::Environment::HasEnvironment::HasEnvironment>::EnvironmentType:
27			Requires<TCapabilityProvider>,
28		TError: From<CommonError> + Send + Sync + 'static,
29		TOutput: Send + Sync + 'static, {
30		let (ResultSender, ResultReceiver) = tokio::sync::oneshot::channel::<Result<TOutput, TError>>();
31
32		let CapabilityProvider:Arc<TCapabilityProvider> = self.Environment.Require();
33
34		let Task = async move {
35			let Result = Effect.Apply(CapabilityProvider).await;
36
37			if ResultSender.send(Result).is_err() {
38				dev_log!(
39					"lifecycle",
40					"error: [ApplicationRunTime] Failed to send effect result; receiver was dropped."
41				);
42			}
43		};
44
45		self.Scheduler.Submit(Task, Priority::Normal);
46
47		match ResultReceiver.await {
48			Ok(Result) => Result,
49
50			Err(_) => {
51				let Message = "Effect execution canceled; oneshot channel closed.".to_string();
52
53				dev_log!("lifecycle", "error: {}", Message);
54
55				Err(CommonError::IPCError { Description:Message }.into())
56			},
57		}
58	}
59}