reifydb_sub_server_http/
factory.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later
3
4//! Factory for creating HTTP subsystem instances.
5
6use std::{sync::Arc, time::Duration};
7
8use reifydb_core::ioc::IocContainer;
9use reifydb_engine::{StandardCommandTransaction, StandardEngine};
10use reifydb_sub_api::{Subsystem, SubsystemFactory};
11use reifydb_sub_server::{AppState, QueryConfig, SharedRuntime};
12
13use crate::HttpSubsystem;
14
15/// Configuration for the HTTP server subsystem.
16#[derive(Clone)]
17pub struct HttpConfig {
18	/// Address to bind the HTTP server to (e.g., "0.0.0.0:8091").
19	pub bind_addr: String,
20	/// Maximum number of concurrent connections.
21	pub max_connections: usize,
22	/// Timeout for query execution.
23	pub query_timeout: Duration,
24	/// Timeout for entire request lifecycle.
25	pub request_timeout: Duration,
26	/// Optional shared runtime. If not provided, a default one will be created.
27	pub runtime: Option<Arc<SharedRuntime>>,
28}
29
30impl std::fmt::Debug for HttpConfig {
31	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32		f.debug_struct("HttpConfig")
33			.field("bind_addr", &self.bind_addr)
34			.field("max_connections", &self.max_connections)
35			.field("query_timeout", &self.query_timeout)
36			.field("request_timeout", &self.request_timeout)
37			.field("runtime", &self.runtime.as_ref().map(|_| "SharedRuntime"))
38			.finish()
39	}
40}
41
42impl Default for HttpConfig {
43	fn default() -> Self {
44		Self {
45			bind_addr: "0.0.0.0:8091".to_string(),
46			max_connections: 10_000,
47			query_timeout: Duration::from_secs(30),
48			request_timeout: Duration::from_secs(60),
49			runtime: None,
50		}
51	}
52}
53
54impl HttpConfig {
55	/// Create a new HTTP config with default values.
56	pub fn new() -> Self {
57		Self::default()
58	}
59
60	/// Set the bind address.
61	pub fn bind_addr(mut self, addr: impl Into<String>) -> Self {
62		self.bind_addr = addr.into();
63		self
64	}
65
66	/// Set the maximum number of connections.
67	pub fn max_connections(mut self, max: usize) -> Self {
68		self.max_connections = max;
69		self
70	}
71
72	/// Set the query timeout.
73	pub fn query_timeout(mut self, timeout: Duration) -> Self {
74		self.query_timeout = timeout;
75		self
76	}
77
78	/// Set the request timeout.
79	pub fn request_timeout(mut self, timeout: Duration) -> Self {
80		self.request_timeout = timeout;
81		self
82	}
83
84	/// Set the shared runtime.
85	pub fn runtime(mut self, runtime: Arc<SharedRuntime>) -> Self {
86		self.runtime = Some(runtime);
87		self
88	}
89}
90
91/// Factory for creating HTTP subsystem instances.
92pub struct HttpSubsystemFactory {
93	config: HttpConfig,
94}
95
96impl HttpSubsystemFactory {
97	/// Create a new HTTP subsystem factory with the given configuration.
98	pub fn new(config: HttpConfig) -> Self {
99		Self {
100			config,
101		}
102	}
103}
104
105impl SubsystemFactory<StandardCommandTransaction> for HttpSubsystemFactory {
106	fn create(self: Box<Self>, ioc: &IocContainer) -> reifydb_type::Result<Box<dyn Subsystem>> {
107		let engine = ioc.resolve::<StandardEngine>()?;
108
109		// Use provided runtime or create a default one
110		let runtime = self.config.runtime.unwrap_or_else(|| Arc::new(SharedRuntime::default()));
111
112		let query_config = QueryConfig::new()
113			.query_timeout(self.config.query_timeout)
114			.request_timeout(self.config.request_timeout)
115			.max_connections(self.config.max_connections);
116
117		let state = AppState::new(engine, query_config);
118		let subsystem = HttpSubsystem::with_runtime(self.config.bind_addr.clone(), state, runtime);
119
120		Ok(Box::new(subsystem))
121	}
122}