dmsc/core/module.rs
1//! Copyright © 2025-2026 Wenze Wei. All Rights Reserved.
2//!
3//! This file is part of DMSC.
4//! The DMSC project belongs to the Dunimd Team.
5//!
6//! Licensed under the Apache License, Version 2.0 (the "License");
7//! You may not use this file except in compliance with the License.
8//! You may obtain a copy of the License at
9//!
10//! http://www.apache.org/licenses/LICENSE-2.0
11//!
12//! Unless required by applicable law or agreed to in writing, software
13//! distributed under the License is distributed on an "AS IS" BASIS,
14//! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15//! See the License for the specific language governing permissions and
16//! limitations under the License.
17
18//! # Core Module System
19//!
20//! This module provides the foundation for modular service architecture in DMSC.
21//! It defines traits and structures for both synchronous and asynchronous service modules.
22//!
23//! ## Key Components
24//!
25//! - **ServiceModule**: Trait for synchronous service modules
26//! - **AsyncServiceModule**: Trait for asynchronous service modules
27//! - **DMSCModule**: Public async trait for DMSC modules
28//! - **DMSCPythonModuleAdapter**: Python module adapter
29//!
30//! ## Design Principles
31//!
32//! 1. **Lifecycle Management**: Modules follow a well-defined lifecycle with multiple phases
33//! 2. **Sync/Async Support**: Clear separation between synchronous and asynchronous modules
34//! 3. **Default Implementations**: Most methods have sensible defaults to minimize boilerplate
35//! 4. **Dependency Resolution**: Modules can declare dependencies on other modules
36//! 5. **Priority System**: Modules can specify execution priority
37//! 6. **Criticality Flag**: Modules can be marked as critical or non-critical
38//!
39//! ## Module Lifecycle
40//!
41//! Modules go through the following lifecycle phases:
42//!
43//! 1. **Initialization**: `init` - Set up module resources
44//! 2. **Before Start**: `before_start` - Prepare for module startup
45//! 3. **Start**: `start` - Start module execution
46//! 4. **After Start**: `after_start` - Post-startup operations
47//! 5. **Before Shutdown**: `before_shutdown` - Prepare for shutdown
48//! 6. **Shutdown**: `shutdown` - Stop module execution
49//! 7. **After Shutdown**: `after_shutdown` - Cleanup resources
50
51use crate::core::{DMSCResult, DMSCServiceContext};
52
53/// Synchronous service module trait.
54///
55/// This trait defines the interface for synchronous service modules in DMSC. It provides
56/// a comprehensive lifecycle management system with multiple phases.
57///
58/// ## Usage
59///
60/// ```rust
61/// use dmsc::core::{ServiceModule, DMSCResult, DMSCServiceContext};
62///
63/// struct MySyncModule;
64///
65/// impl ServiceModule for MySyncModule {
66/// fn name(&self) -> &str {
67/// "my_sync_module"
68/// }
69///
70/// fn is_critical(&self) -> bool {
71/// false
72/// }
73///
74/// fn priority(&self) -> i32 {
75/// 10
76/// }
77///
78/// fn dependencies(&self) -> Vec<&str> {
79/// vec!["dependency_module"]
80/// }
81///
82/// fn start(&mut self, ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
83/// // Start module logic
84/// Ok(())
85/// }
86/// }
87/// ```
88pub trait ServiceModule: Send + Sync {
89 /// Returns the name of the service module.
90 ///
91 /// This name is used for identification, dependency resolution, and logging purposes.
92 fn name(&self) -> &str;
93
94 /// Indicates if the module is critical to the operation of the system.
95 ///
96 /// Critical modules will cause the entire system to fail if they encounter an error,
97 /// while non-critical modules can fail independently.
98 ///
99 /// Default: `true`
100 fn is_critical(&self) -> bool {
101 true
102 }
103
104 /// Returns the priority of the module.
105 ///
106 /// Modules with higher priority are executed first within the same dependency level.
107 ///
108 /// Default: `0`
109 fn priority(&self) -> i32 {
110 0
111 }
112
113 /// Returns the list of module dependencies.
114 ///
115 /// Dependencies are module names that must be initialized and started before this module.
116 /// The runtime will ensure dependencies are processed in the correct order.
117 ///
118 /// Default: `Vec::new()`
119 fn dependencies(&self) -> Vec<&str> {
120 Vec::new()
121 }
122
123 /// Initializes the service module.
124 ///
125 /// This method is called during the initialization phase to set up module resources.
126 ///
127 /// Default: `Ok(())`
128 fn init(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
129 Ok(())
130 }
131
132 /// Prepares the module for startup.
133 ///
134 /// This method is called after initialization but before the main start phase.
135 ///
136 /// Default: `Ok(())`
137 fn before_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
138 Ok(())
139 }
140
141 /// Starts the service module.
142 ///
143 /// This method is called to start the main functionality of the module.
144 ///
145 /// Default: `Ok(())`
146 fn start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
147 Ok(())
148 }
149
150 /// Performs post-startup operations.
151 ///
152 /// This method is called after the main start phase but before the module is considered fully started.
153 ///
154 /// Default: `Ok(())`
155 fn after_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
156 Ok(())
157 }
158
159 /// Prepares the module for shutdown.
160 ///
161 /// This method is called before the main shutdown phase.
162 ///
163 /// Default: `Ok(())`
164 fn before_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
165 Ok(())
166 }
167
168 /// Shuts down the service module.
169 ///
170 /// This method is called to stop the main functionality of the module.
171 ///
172 /// Default: `Ok(())`
173 fn shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
174 Ok(())
175 }
176
177 /// Performs post-shutdown cleanup.
178 ///
179 /// This method is called after the main shutdown phase to clean up resources.
180 ///
181 /// Default: `Ok(())`
182 fn after_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
183 Ok(())
184 }
185}
186
187/// Public asynchronous service module trait.
188///
189/// This trait defines the public interface for asynchronous service modules in DMSC.
190/// It provides a comprehensive lifecycle management system with multiple phases.
191///
192/// ## Usage
193///
194/// ```rust
195/// use dmsc::core::{DMSCModule, DMSCResult, DMSCServiceContext};
196/// use async_trait::async_trait;
197///
198/// struct MyAsyncModule;
199///
200/// #[async_trait]
201/// impl DMSCModule for MyAsyncModule {
202/// fn name(&self) -> &str {
203/// "my_async_module"
204/// }
205///
206/// async fn start(&mut self, ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
207/// // Start async module logic
208/// Ok(())
209/// }
210/// }
211/// ```
212#[async_trait::async_trait]
213pub trait DMSCModule: Send + Sync {
214 /// Returns the name of the service module.
215 ///
216 /// This name is used for identification, dependency resolution, and logging purposes.
217 fn name(&self) -> &str;
218
219 /// Indicates if the module is critical to the operation of the system.
220 ///
221 /// Critical modules will cause the entire system to fail if they encounter an error,
222 /// while non-critical modules can fail independently.
223 ///
224 /// Default: `true`
225 fn is_critical(&self) -> bool {
226 true
227 }
228
229 /// Returns the priority of the module.
230 ///
231 /// Modules with higher priority are executed first within the same dependency level.
232 ///
233 /// Default: `0`
234 fn priority(&self) -> i32 {
235 0
236 }
237
238 /// Returns the list of module dependencies.
239 ///
240 /// Dependencies are module names that must be initialized and started before this module.
241 /// The runtime will ensure dependencies are processed in the correct order.
242 ///
243 /// Default: `Vec::new()`
244 fn dependencies(&self) -> Vec<&str> {
245 Vec::new()
246 }
247
248 /// Initializes the service module.
249 ///
250 /// This method is called during the initialization phase to set up module resources.
251 ///
252 /// Default: `Ok(())`
253 async fn init(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
254 Ok(())
255 }
256
257 /// Prepares the module for startup.
258 ///
259 /// This method is called after initialization but before the main start phase.
260 ///
261 /// Default: `Ok(())`
262 async fn before_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
263 Ok(())
264 }
265
266 /// Starts the service module.
267 ///
268 /// This method is called to start the main functionality of the module.
269 ///
270 /// Default: `Ok(())`
271 async fn start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
272 Ok(())
273 }
274
275 /// Performs post-startup operations.
276 ///
277 /// This method is called after the main start phase but before the module is considered fully started.
278 ///
279 /// Default: `Ok(())`
280 async fn after_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
281 Ok(())
282 }
283
284 /// Prepares the module for shutdown.
285 ///
286 /// This method is called before the main shutdown phase.
287 ///
288 /// Default: `Ok(())`
289 async fn before_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
290 Ok(())
291 }
292
293 /// Shuts down the service module.
294 ///
295 /// This method is called to stop the main functionality of the module.
296 ///
297 /// Default: `Ok(())`
298 async fn shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
299 Ok(())
300 }
301
302 /// Performs post-shutdown cleanup.
303 ///
304 /// This method is called after the main shutdown phase to clean up resources.
305 ///
306 /// Default: `Ok(())`
307 async fn after_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
308 Ok(())
309 }
310}
311
312#[cfg(feature = "pyo3")]
313use pyo3::prelude::*;
314
315#[cfg(feature = "pyo3")]
316/// Python representation of a DMSC module configuration.
317///
318/// This structure provides a Python-accessible view of module configuration,
319/// allowing Python code to define module properties that can be used in Rust.
320/// It serves as a data container for module metadata and lifecycle configuration.
321///
322/// ## Attributes
323///
324/// - **name**: The unique identifier for the module
325/// - **is_critical**: Whether the module is critical to system operation
326/// - **priority**: Execution priority for dependency resolution
327/// - **dependencies**: List of module names this module depends on
328///
329/// ## Python Usage
330///
331/// ```python
332///
333///
334/// module = dms.DMSCPythonModule(name="my_python_module")
335/// module.is_critical = True
336/// module.priority = 100
337/// module.dependencies = ["logger", "config"]
338/// ```
339#[pyclass]
340#[pyo3(name = "DMSCPythonModule")]
341#[derive(Clone)]
342pub struct DMSCPythonModule {
343 #[pyo3(get)]
344 name: String,
345 #[pyo3(get)]
346 is_critical: bool,
347 #[pyo3(get)]
348 priority: i32,
349 #[pyo3(get)]
350 dependencies: Vec<String>,
351}
352
353#[cfg(feature = "pyo3")]
354#[pymethods]
355impl DMSCPythonModule {
356 #[new]
357 fn new(name: String) -> Self {
358 DMSCPythonModule {
359 name,
360 is_critical: true,
361 priority: 0,
362 dependencies: Vec::new(),
363 }
364 }
365
366 #[getter]
367 pub fn name(&self) -> String {
368 self.name.clone()
369 }
370
371 #[setter]
372 pub fn set_name(&mut self, name: String) {
373 self.name = name;
374 }
375
376 #[getter]
377 pub fn is_critical(&self) -> bool {
378 self.is_critical
379 }
380
381 #[setter]
382 pub fn set_is_critical(&mut self, is_critical: bool) {
383 self.is_critical = is_critical;
384 }
385
386 #[getter]
387 pub fn priority(&self) -> i32 {
388 self.priority
389 }
390
391 #[setter]
392 pub fn set_priority(&mut self, priority: i32) {
393 self.priority = priority;
394 }
395
396 #[getter]
397 pub fn dependencies(&self) -> Vec<String> {
398 self.dependencies.clone()
399 }
400
401 #[setter]
402 pub fn set_dependencies(&mut self, dependencies: Vec<String>) {
403 self.dependencies = dependencies;
404 }
405}
406
407#[cfg(feature = "pyo3")]
408/// Python module adapter that implements DMSCModule trait.
409///
410/// This structure enables Python modules to integrate with the DMSC module system
411/// by implementing the `AsyncServiceModule` trait. Python code can create instances
412/// of this adapter with custom configuration, and they will participate in the
413/// module lifecycle just like Rust-native modules.
414///
415/// ## Thread Safety
416///
417/// This structure is designed to be safely used across threads when combined
418/// with the appropriate Python GIL management. The underlying implementation
419/// ensures proper synchronization during lifecycle callbacks.
420///
421/// ## Lifecycle Methods
422///
423/// All lifecycle methods (`init`, `before_start`, `start`, `after_start`,
424/// `before_shutdown`, `shutdown`, `after_shutdown`) have default implementations
425/// that return `Ok(())`, allowing Python modules to override only the methods
426/// they need.
427///
428/// ## Python Usage
429///
430/// ```python
431///
432///
433/// class MyPythonModule:
434/// def name(&self):
435/// return "python_module"
436///
437/// async def start(&self, ctx):
438/// print("Starting Python module")
439/// return None
440///
441/// adapter = dms.DMSCPythonModuleAdapter(name="my_module")
442/// adapter.name = "python_module"
443/// ```
444#[pyclass]
445#[derive(Clone)]
446pub struct DMSCPythonModuleAdapter {
447 #[pyo3(get, set)]
448 pub name: String,
449 #[pyo3(get, set)]
450 pub is_critical: bool,
451 #[pyo3(get, set)]
452 pub priority: i32,
453 #[pyo3(get, set)]
454 pub dependencies: Vec<String>,
455}
456
457#[cfg(feature = "pyo3")]
458#[pymethods]
459impl DMSCPythonModuleAdapter {
460 #[new]
461 fn new(name: String) -> Self {
462 DMSCPythonModuleAdapter {
463 name,
464 is_critical: true,
465 priority: 0,
466 dependencies: Vec::new(),
467 }
468 }
469}
470
471#[cfg(feature = "pyo3")]
472/// Python wrapper for synchronous ServiceModule trait.
473///
474/// This structure provides a Python-accessible representation of synchronous
475/// service modules. It enables Python code to define synchronous modules that
476/// integrate with DMSC's module lifecycle system. Unlike asynchronous modules,
477/// synchronous modules execute their operations in a blocking manner.
478///
479/// ## Synchronous vs Asynchronous
480///
481/// Synchronous modules use blocking I/O and execute their callbacks on the
482/// same thread as the module lifecycle manager. For non-blocking operations,
483/// use `DMSCPythonAsyncServiceModule` instead.
484///
485/// ## Threading Model
486///
487/// Synchronous modules are executed in the context of the module management
488/// thread. Long-running operations will block the entire module system.
489/// Consider using `tokio::task::spawn_blocking` for CPU-intensive work.
490///
491/// ## Default Behavior
492///
493/// All lifecycle methods return `Ok(())` by default, allowing Python modules
494/// to override only the methods they need to customize.
495///
496/// ## Python Usage
497///
498/// ```python
499///
500///
501/// class MySyncModule:
502/// def name(&self):
503/// return "sync_module"
504///
505/// def start(&self, ctx):
506/// print("Starting sync module")
507/// return None
508///
509/// module = dms.DMSCPythonServiceModule(name="my_sync")
510/// module.priority = 50
511/// module.dependencies = ["config"]
512/// ```
513#[pyclass(subclass)]
514#[derive(Clone)]
515pub struct DMSCPythonServiceModule {
516 name: String,
517 is_critical: bool,
518 priority: i32,
519 dependencies: Vec<String>,
520}
521
522#[cfg(feature = "pyo3")]
523#[pymethods]
524impl DMSCPythonServiceModule {
525 #[new]
526 fn new(name: String) -> Self {
527 DMSCPythonServiceModule {
528 name,
529 is_critical: true,
530 priority: 0,
531 dependencies: Vec::new(),
532 }
533 }
534
535 #[getter]
536 pub fn name(&self) -> String {
537 self.name.clone()
538 }
539
540 #[setter]
541 pub fn set_name(&mut self, name: String) {
542 self.name = name;
543 }
544
545 #[getter]
546 pub fn is_critical(&self) -> bool {
547 self.is_critical
548 }
549
550 #[setter]
551 pub fn set_is_critical(&mut self, is_critical: bool) {
552 self.is_critical = is_critical;
553 }
554
555 #[getter]
556 pub fn priority(&self) -> i32 {
557 self.priority
558 }
559
560 #[setter]
561 pub fn set_priority(&mut self, priority: i32) {
562 self.priority = priority;
563 }
564
565 #[getter]
566 pub fn dependencies(&self) -> Vec<String> {
567 self.dependencies.clone()
568 }
569
570 #[setter]
571 pub fn set_dependencies(&mut self, dependencies: Vec<String>) {
572 self.dependencies = dependencies;
573 }
574}
575
576#[cfg(feature = "pyo3")]
577/// Python wrapper for asynchronous AsyncServiceModule trait.
578///
579/// This structure provides a Python-accessible representation of asynchronous
580/// service modules. It enables Python code to define async modules that integrate
581/// with DMSC's module lifecycle system using non-blocking operations.
582///
583/// ## Asynchronous Execution
584///
585/// Asynchronous modules use Rust's async/await model and are executed on the
586/// Tokio runtime. This enables non-blocking I/O operations and concurrent
587/// execution of multiple async modules without thread blocking.
588///
589/// ## Tokio Runtime
590///
591/// The async modules execute within the Tokio runtime that is managed by the
592/// DMSC application runtime. This provides efficient task scheduling and
593/// native support for async I/O operations.
594///
595/// ## Python Integration
596///
597/// When using Python with pyo3, asynchronous methods should be defined using
598/// async def syntax. The Python runtime must be properly initialized before
599/// async operations can be performed.
600///
601/// ## Python Usage
602///
603/// ```python
604///
605///
606/// class MyAsyncModule:
607/// async def name(&self):
608/// return "async_module"
609///
610/// async def start(&self, ctx):
611/// print("Starting async module")
612/// return None
613///
614/// module = dms.DMSCPythonAsyncServiceModule(name="my_async")
615/// module.priority = 100
616/// module.dependencies = ["config", "logger"]
617/// ```
618#[pyclass(subclass)]
619#[derive(Clone)]
620pub struct DMSCPythonAsyncServiceModule {
621 name: String,
622 is_critical: bool,
623 priority: i32,
624 dependencies: Vec<String>,
625}
626
627#[cfg(feature = "pyo3")]
628#[pymethods]
629impl DMSCPythonAsyncServiceModule {
630 #[new]
631 fn new(name: String) -> Self {
632 DMSCPythonAsyncServiceModule {
633 name,
634 is_critical: true,
635 priority: 0,
636 dependencies: Vec::new(),
637 }
638 }
639
640 #[getter]
641 pub fn name(&self) -> String {
642 self.name.clone()
643 }
644
645 #[setter]
646 pub fn set_name(&mut self, name: String) {
647 self.name = name;
648 }
649
650 #[getter]
651 pub fn is_critical(&self) -> bool {
652 self.is_critical
653 }
654
655 #[setter]
656 pub fn set_is_critical(&mut self, is_critical: bool) {
657 self.is_critical = is_critical;
658 }
659
660 #[getter]
661 pub fn priority(&self) -> i32 {
662 self.priority
663 }
664
665 #[setter]
666 pub fn set_priority(&mut self, priority: i32) {
667 self.priority = priority;
668 }
669
670 #[getter]
671 pub fn dependencies(&self) -> Vec<String> {
672 self.dependencies.clone()
673 }
674
675 #[setter]
676 pub fn set_dependencies(&mut self, dependencies: Vec<String>) {
677 self.dependencies = dependencies;
678 }
679}
680
681#[cfg(feature = "pyo3")]
682#[async_trait::async_trait]
683impl AsyncServiceModule for DMSCPythonModuleAdapter {
684 fn name(&self) -> &str {
685 &self.name
686 }
687
688 fn is_critical(&self) -> bool {
689 self.is_critical
690 }
691
692 fn priority(&self) -> i32 {
693 self.priority
694 }
695
696 fn dependencies(&self) -> Vec<&str> {
697 self.dependencies.iter().map(|s| s.as_str()).collect()
698 }
699
700 async fn init(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
701 Ok(())
702 }
703
704 async fn before_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
705 Ok(())
706 }
707
708 async fn start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
709 Ok(())
710 }
711
712 async fn after_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
713 Ok(())
714 }
715
716 async fn before_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
717 Ok(())
718 }
719
720 async fn shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
721 Ok(())
722 }
723
724 async fn after_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
725 Ok(())
726 }
727}
728
729#[cfg(feature = "pyo3")]
730impl ServiceModule for DMSCPythonServiceModule {
731 fn name(&self) -> &str {
732 &self.name
733 }
734
735 fn is_critical(&self) -> bool {
736 self.is_critical
737 }
738
739 fn priority(&self) -> i32 {
740 self.priority
741 }
742
743 fn dependencies(&self) -> Vec<&str> {
744 self.dependencies.iter().map(|s| s.as_str()).collect()
745 }
746
747 fn init(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
748 Ok(())
749 }
750
751 fn before_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
752 Ok(())
753 }
754
755 fn start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
756 Ok(())
757 }
758
759 fn after_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
760 Ok(())
761 }
762
763 fn before_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
764 Ok(())
765 }
766
767 fn shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
768 Ok(())
769 }
770
771 fn after_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
772 Ok(())
773 }
774}
775
776#[cfg(feature = "pyo3")]
777#[async_trait::async_trait]
778impl AsyncServiceModule for DMSCPythonAsyncServiceModule {
779 fn name(&self) -> &str {
780 &self.name
781 }
782
783 fn is_critical(&self) -> bool {
784 self.is_critical
785 }
786
787 fn priority(&self) -> i32 {
788 self.priority
789 }
790
791 fn dependencies(&self) -> Vec<&str> {
792 self.dependencies.iter().map(|s| s.as_str()).collect()
793 }
794
795 async fn init(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
796 Ok(())
797 }
798
799 async fn before_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
800 Ok(())
801 }
802
803 async fn start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
804 Ok(())
805 }
806
807 async fn after_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
808 Ok(())
809 }
810
811 async fn before_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
812 Ok(())
813 }
814
815 async fn shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
816 Ok(())
817 }
818
819 async fn after_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
820 Ok(())
821 }
822}
823
824
825/// Internal asynchronous service module trait.
826///
827/// This trait defines the interface for internal asynchronous service modules in DMSC.
828/// It provides a comprehensive lifecycle management system with multiple phases.
829///
830/// ## Usage
831///
832/// ```rust
833/// use dmsc::core::{AsyncServiceModule, DMSCResult, DMSCServiceContext};
834/// use async_trait::async_trait;
835///
836/// struct MyInternalAsyncModule;
837///
838/// #[async_trait]
839/// impl AsyncServiceModule for MyInternalAsyncModule {
840/// fn name(&self) -> &str {
841/// "my_internal_async_module"
842/// }
843///
844/// async fn start(&mut self, ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
845/// // Start internal async module logic
846/// Ok(())
847/// }
848/// }
849/// ```
850#[async_trait::async_trait]
851pub trait AsyncServiceModule: Send + Sync {
852 /// Returns the name of the internal async service module.
853 ///
854 /// This name is used for identification, dependency resolution, and logging purposes.
855 fn name(&self) -> &str;
856
857 /// Indicates if the internal module is critical to the operation of the system.
858 ///
859 /// Critical modules will cause the entire system to fail if they encounter an error,
860 /// while non-critical modules can fail independently.
861 ///
862 /// Default: `true`
863 fn is_critical(&self) -> bool {
864 true
865 }
866
867 /// Returns the priority of the internal module.
868 ///
869 /// Modules with higher priority are executed first within the same dependency level.
870 ///
871 /// Default: `0`
872 fn priority(&self) -> i32 {
873 0
874 }
875
876 /// Returns the list of module dependencies.
877 ///
878 /// Dependencies are module names that must be initialized and started before this module.
879 /// The runtime will ensure dependencies are processed in the correct order.
880 ///
881 /// Default: `Vec::new()`
882 fn dependencies(&self) -> Vec<&str> {
883 Vec::new()
884 }
885
886 /// Initializes the internal async service module.
887 ///
888 /// This method is called during the initialization phase to set up module resources.
889 ///
890 /// Default: `Ok(())`
891 async fn init(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
892 Ok(())
893 }
894
895 /// Prepares the internal module for startup.
896 ///
897 /// This method is called after initialization but before the main start phase.
898 ///
899 /// Default: `Ok(())`
900 async fn before_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
901 Ok(())
902 }
903
904 /// Starts the internal async service module.
905 ///
906 /// This method is called to start the main functionality of the module.
907 ///
908 /// Default: `Ok(())`
909 async fn start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
910 Ok(())
911 }
912
913 /// Performs post-startup operations for the internal module.
914 ///
915 /// This method is called after the main start phase but before the module is considered fully started.
916 ///
917 /// Default: `Ok(())`
918 async fn after_start(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
919 Ok(())
920 }
921
922 /// Prepares the internal module for shutdown.
923 ///
924 /// This method is called before the main shutdown phase.
925 ///
926 /// Default: `Ok(())`
927 async fn before_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
928 Ok(())
929 }
930
931 /// Shuts down the internal async service module.
932 ///
933 /// This method is called to stop the main functionality of the module.
934 ///
935 /// Default: `Ok(())`
936 async fn shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
937 Ok(())
938 }
939
940 /// Performs post-shutdown cleanup for the internal module.
941 ///
942 /// This method is called after the main shutdown phase to clean up resources.
943 ///
944 /// Default: `Ok(())`
945 async fn after_shutdown(&mut self, _ctx: &mut DMSCServiceContext) -> DMSCResult<()> {
946 Ok(())
947 }
948}