Skip to main content

reifydb_sub_api/
subsystem.rs

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