1use crate::finalizer::{BoxFinalizer, Finalizer};
2use crate::routine::Routine;
3use async_trait::async_trait;
4use crb_core::time::Duration;
5use crb_runtime::kit::{
6 Context, Controller, Failures, InteractiveRuntime, Interruptor, ManagedContext, Runtime,
7};
8
9pub struct RoutineRuntime<R: Routine> {
10 pub routine: R,
11 pub context: R::Context,
12 pub failures: Failures,
13}
14
15impl<R: Routine> RoutineRuntime<R> {
16 pub fn new(routine: R) -> Self
17 where
18 R::Context: Default,
19 {
20 Self {
21 routine,
22 context: R::Context::default(),
23 failures: Failures::default(),
24 }
25 }
26}
27
28#[async_trait]
29impl<R: Routine> InteractiveRuntime for RoutineRuntime<R> {
30 type Context = R::Context;
31
32 fn address(&self) -> <Self::Context as Context>::Address {
33 self.context.address().clone()
34 }
35}
36
37#[async_trait]
38impl<R: Routine> Runtime for RoutineRuntime<R> {
39 fn get_interruptor(&mut self) -> Interruptor {
40 self.context.session().controller().interruptor.clone()
41 }
42
43 async fn routine(&mut self) {
44 let ctx = &mut self.context;
45 let result = self.routine.routine(ctx).await;
46 self.failures.put(result);
47 }
48}
49
50pub struct RoutineSession<R: Routine> {
51 controller: Controller,
52 interval: Duration,
54 finalizer: Option<BoxFinalizer<R::Output>>,
55}
56
57impl<R: Routine> Default for RoutineSession<R> {
58 fn default() -> Self {
59 let controller = Controller::default();
60 Self {
61 controller,
62 interval: Duration::from_secs(5),
63 finalizer: None,
64 }
65 }
66}
67
68impl<R: Routine> RoutineSession<R> {
69 pub fn set_interval(&mut self, interval: Duration) {
71 self.interval = interval;
72 }
73
74 pub fn interval(&self) -> Duration {
75 self.interval
76 }
77
78 pub fn set_finalizer(&mut self, finalizer: impl Finalizer<R::Output>) {
79 self.finalizer = Some(Box::new(finalizer));
80 }
81
82 pub fn take_finalizer(&mut self) -> Option<BoxFinalizer<R::Output>> {
83 self.finalizer.take()
84 }
85}
86
87impl<R: Routine> Context for RoutineSession<R> {
88 type Address = ();
90
91 fn address(&self) -> &Self::Address {
92 &()
93 }
94}
95
96impl<R: Routine> ManagedContext for RoutineSession<R> {
97 fn controller(&mut self) -> &mut Controller {
98 &mut self.controller
99 }
100
101 fn shutdown(&mut self) {
102 self.controller.stop(false).ok();
103 }
104}
105
106pub trait RoutineContext<R: Routine>: Context {
107 fn session(&mut self) -> &mut RoutineSession<R>;
108}
109
110impl<R: Routine> RoutineContext<R> for RoutineSession<R> {
111 fn session(&mut self) -> &mut RoutineSession<R> {
112 self
113 }
114}