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
23		Effect:ActionEffect<Arc<TCapabilityProvider>, TError, TOutput>,
24	) -> Result<TOutput, TError>
25	where
26		TCapabilityProvider: ?Sized + Send + Sync + 'static,
27		<Self as CommonLibrary::Environment::HasEnvironment::HasEnvironment>::EnvironmentType:
28			Requires<TCapabilityProvider>,
29		TError: From<CommonError> + Send + Sync + 'static,
30		TOutput: Send + Sync + 'static, {
31		let (ResultSender, ResultReceiver) = tokio::sync::oneshot::channel::<Result<TOutput, TError>>();
32
33		let CapabilityProvider:Arc<TCapabilityProvider> = self.Environment.Require();
34
35		let Task = async move {
36			let Result = Effect.Apply(CapabilityProvider).await;
37
38			if ResultSender.send(Result).is_err() {
39				dev_log!(
40					"lifecycle",
41					"error: [ApplicationRunTime] Failed to send effect result; receiver was dropped."
42				);
43			}
44		};
45
46		self.Scheduler.Submit(Task, Priority::Normal);
47
48		match ResultReceiver.await {
49			Ok(Result) => Result,
50
51			Err(_) => {
52				let Message = "Effect execution canceled; oneshot channel closed.".to_string();
53
54				dev_log!("lifecycle", "error: {}", Message);
55
56				Err(CommonError::IPCError { Description:Message }.into())
57			},
58		}
59	}
60}