Skip to main content

reifydb_sub_api/
subsystem.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2025 ReifyDB
3
4use std::any::Any;
5
6use reifydb_core::{interface::version::HasVersion, util::ioc::IocContainer};
7use reifydb_transaction::interceptor::builder::InterceptorBuilder;
8use reifydb_type::Result;
9
10/// Uniform interface that all subsystems must implement
11///
12/// This trait provides a consistent lifecycle and monitoring interface
13/// for all subsystems managed by the Database.
14pub trait Subsystem: Any + HasVersion {
15	/// Get the unique name of this subsystem
16	fn name(&self) -> &'static str;
17	/// Start the subsystem
18	///
19	/// This method should initialize the subsystem and start any background
20	/// threads or processes. It should be idempotent - calling start() on
21	/// an already running subsystem should succeed without side effects.
22	fn start(&mut self) -> Result<()>;
23	/// Shutdown the subsystem
24	///
25	/// This method should gracefully shut down the subsystem and clean up
26	/// any resources. This is a terminal operation - once shutdown, the
27	/// subsystem cannot be restarted. It should be idempotent - calling
28	/// shutdown() on an already shutdown subsystem should succeed without
29	/// side effects.
30	fn shutdown(&mut self) -> Result<()>;
31
32	/// Check if the subsystem is currently running
33	fn is_running(&self) -> bool;
34
35	/// Get the current health status of the subsystem
36	///
37	/// This should provide information about the subsystem's operational
38	/// status and any errors or warnings.
39	fn health_status(&self) -> HealthStatus;
40
41	/// Get a reference to self as Any for downcasting
42	fn as_any(&self) -> &dyn Any;
43
44	/// Get a mutable reference to self as Any for downcasting
45	fn as_any_mut(&mut self) -> &mut dyn Any;
46}
47
48/// Factory trait for creating subsystems with IoC support
49pub trait SubsystemFactory: Send {
50	fn provide_interceptors(&self, builder: InterceptorBuilder, _ioc: &IocContainer) -> InterceptorBuilder {
51		builder
52	}
53
54	fn create(self: Box<Self>, ioc: &IocContainer) -> Result<Box<dyn Subsystem>>;
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub enum HealthStatus {
59	Healthy,
60	Warning {
61		description: String,
62	},
63	Degraded {
64		description: String,
65	},
66	Failed {
67		description: String,
68	},
69	Unknown,
70}
71
72impl HealthStatus {
73	pub fn is_healthy(&self) -> bool {
74		matches!(self, HealthStatus::Healthy)
75	}
76
77	pub fn is_failed(&self) -> bool {
78		matches!(self, HealthStatus::Failed { .. })
79	}
80
81	pub fn description(&self) -> &str {
82		match self {
83			HealthStatus::Healthy => "Healthy",
84			HealthStatus::Warning {
85				description: message,
86			} => message,
87			HealthStatus::Degraded {
88				description: message,
89			} => message,
90			HealthStatus::Failed {
91				description: message,
92			} => message,
93			HealthStatus::Unknown => "Unknown",
94		}
95	}
96}