reifydb_sub_server/subsystem/
server.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4use std::any::Any;
5
6use reifydb_core::interface::version::{ComponentType, HasVersion, SystemVersion};
7use reifydb_engine::StandardEngine;
8use reifydb_sub_api::{HealthStatus, SchedulerService, Subsystem};
9use reifydb_type::{diagnostic::internal::internal, error};
10
11use crate::{config::ServerConfig, core::ProtocolServer};
12
13/// Server subsystem that supports WebSocket and HTTP protocols
14pub struct ServerSubsystem {
15	config: ServerConfig,
16	server: Option<ProtocolServer>,
17	engine: StandardEngine,
18	scheduler: SchedulerService,
19}
20
21impl ServerSubsystem {
22	pub fn new(config: ServerConfig, engine: StandardEngine, scheduler: SchedulerService) -> Self {
23		Self {
24			config,
25			server: None,
26			engine,
27			scheduler,
28		}
29	}
30
31	/// Get the actual bound port of the server
32	pub fn port(&self) -> Option<u16> {
33		self.server.as_ref().and_then(|s| s.port())
34	}
35}
36
37impl Subsystem for ServerSubsystem {
38	fn name(&self) -> &'static str {
39		"sub-server"
40	}
41
42	fn start(&mut self) -> reifydb_type::Result<()> {
43		if self.server.is_some() {
44			return Ok(());
45		}
46
47		let mut server = ProtocolServer::new(self.config.clone(), self.engine.clone(), self.scheduler.clone());
48		server.with_websocket().with_http();
49		server.start().map_err(|e| error!(internal(format!("Failed to start server: {:?}", e))))?;
50
51		self.server = Some(server);
52		Ok(())
53	}
54
55	fn shutdown(&mut self) -> reifydb_type::Result<()> {
56		if let Some(mut server) = self.server.take() {
57			// Stopping server
58			server.stop();
59		}
60		Ok(())
61	}
62
63	fn is_running(&self) -> bool {
64		self.server.as_ref().map_or(false, |s| s.is_running())
65	}
66
67	fn health_status(&self) -> HealthStatus {
68		if self.is_running() {
69			HealthStatus::Healthy
70		} else {
71			HealthStatus::Failed {
72				description: "Server is not running".to_string(),
73			}
74		}
75	}
76
77	fn as_any(&self) -> &dyn Any {
78		self
79	}
80
81	fn as_any_mut(&mut self) -> &mut dyn Any {
82		self
83	}
84}
85
86impl HasVersion for ServerSubsystem {
87	fn version(&self) -> SystemVersion {
88		SystemVersion {
89			name: "sub-server".to_string(),
90			version: env!("CARGO_PKG_VERSION").to_string(),
91			description: "Network protocol server subsystem".to_string(),
92			r#type: ComponentType::Subsystem,
93		}
94	}
95}