Skip to main content

Mountain/RunTime/Execute/
Run.rs

1#![allow(non_snake_case)]
2
3//! `ApplicationRunTimeTrait::Run` - submit an `ActionEffect` to the Echo
4//! work-stealing scheduler and block on the oneshot reply.
5
6use std::sync::Arc;
7
8use CommonLibrary::{
9	Effect::{ActionEffect::ActionEffect, ApplicationRunTime::ApplicationRunTime as ApplicationRunTimeTrait},
10	Environment::Requires::Requires,
11	Error::CommonError::CommonError,
12};
13use Echo::Task::Priority::Priority;
14use async_trait::async_trait;
15
16use crate::{RunTime::ApplicationRunTime::ApplicationRunTime, dev_log};
17
18#[async_trait]
19impl ApplicationRunTimeTrait for ApplicationRunTime {
20	async fn Run<TCapabilityProvider, TError, TOutput>(
21		&self,
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			if ResultSender.send(Result).is_err() {
37				dev_log!(
38					"lifecycle",
39					"error: [ApplicationRunTime] Failed to send effect result; receiver was dropped."
40				);
41			}
42		};
43
44		self.Scheduler.Submit(Task, Priority::Normal);
45
46		match ResultReceiver.await {
47			Ok(Result) => Result,
48			Err(_) => {
49				let Message = "Effect execution canceled; oneshot channel closed.".to_string();
50				dev_log!("lifecycle", "error: {}", Message);
51				Err(CommonError::IPCError { Description:Message }.into())
52			},
53		}
54	}
55}