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