rusty_feeder/provider/
config.rs

1use parking_lot::RwLock;
2use quanta::Clock;
3use smallvec::SmallVec;
4use smartstring::alias::String;
5use std::sync::Arc;
6
7use super::timestamp::{TimestampCache, TimestampFormat};
8// Adjusted path
9
10/// Optimized WebSocket configuration with performance options
11#[derive(Debug, Clone)]
12#[repr(align(32))] // Align for better memory access
13pub struct WebSocketConfig {
14    /// Base URL for WebSocket connections
15    pub base_url: String,
16
17    /// Whether to use compression for WebSocket connections
18    pub use_compression: bool,
19
20    /// WebSocket connection timeout in milliseconds
21    pub timeout_milliseconds: u64,
22
23    /// WebSocket ping interval in milliseconds (0 = disabled)
24    pub ping_interval_milliseconds: u64,
25
26    /// Maximum message size in bytes (0 = unlimited)
27    pub max_message_size: usize,
28
29    /// Buffer size for the WebSocket connection
30    pub buffer_size: usize,
31
32    /// Reconnect strategy configuration
33    pub reconnect: ReconnectStrategy,
34
35    /// Protocol version to use (if applicable)
36    pub protocol_version: String,
37
38    /// Heartbeat interval in milliseconds (0 = disabled)
39    /// This is different from ping_interval_milliseconds as it actively monitors connection health
40    pub heartbeat_interval_milliseconds: u64,
41
42    /// Heartbeat timeout in milliseconds
43    /// If no message is received within this time, the connection is considered unhealthy
44    pub heartbeat_timeout_milliseconds: u64,
45
46    /// Maximum number of consecutive missed heartbeats before considering the connection dead
47    pub max_missed_heartbeats: u32,
48
49    /// Whether to enable session failover
50    pub enable_session_failover: bool,
51
52    /// Alternative URLs to connect to if the primary connection fails
53    pub failover_urls: Vec<String>,
54
55    /// Whether to use zero-copy JSON parsing for maximum performance
56    /// This reduces allocations but requires pooled buffers
57    pub use_zero_copy_parsing: bool,
58}
59
60/// WebSocket reconnection strategy
61#[derive(Debug, Clone)]
62pub struct ReconnectStrategy {
63    /// Whether to attempt reconnection
64    pub enabled: bool,
65
66    /// Maximum number of reconnection attempts (0 = unlimited)
67    pub max_attempts: u32,
68
69    /// Initial backoff delay in milliseconds
70    pub backoff_initial_milliseconds: u64,
71
72    /// Maximum backoff delay in milliseconds
73    pub backoff_max_milliseconds: u64,
74
75    /// Backoff multiplier (e.g., 2.0 = exponential backoff)
76    pub backoff_multiplier: f64,
77}
78
79impl Default for ReconnectStrategy {
80    fn default() -> Self {
81        Self {
82            enabled: true,
83            max_attempts: 10,
84            backoff_initial_milliseconds: 100,
85            backoff_max_milliseconds: 30000,
86            backoff_multiplier: 1.5,
87        }
88    }
89}
90
91impl Default for WebSocketConfig {
92    fn default() -> Self {
93        Self {
94            base_url: String::from(""),
95            use_compression: true,
96            timeout_milliseconds: 10000,        // 10 seconds default
97            ping_interval_milliseconds: 30000,  // 30 seconds default
98            max_message_size: 16 * 1024 * 1024, // 16MB default
99            buffer_size: 1024,                  // Default buffer size
100            reconnect: ReconnectStrategy::default(),
101            protocol_version: "".into(),
102            heartbeat_interval_milliseconds: 5000, // 5 seconds default
103            heartbeat_timeout_milliseconds: 10000, // 10 seconds default
104            max_missed_heartbeats: 3, // 3 missed heartbeats before considering connection dead
105            enable_session_failover: false, // Disabled by default
106            failover_urls: Vec::new(), // No failover URLs by default
107            use_zero_copy_parsing: false, // Disabled by default for compatibility
108        }
109    }
110}
111
112/// REST API configuration with performance options
113#[derive(Debug, Clone)]
114#[repr(align(32))] // Align for better memory access
115pub struct RestApiConfig {
116    /// Base URL for REST API connections
117    pub base_url: String,
118
119    /// REST API request timeout in milliseconds
120    pub timeout_milliseconds: u64,
121
122    /// Connection pool size for HTTP client
123    pub connection_pool_size: usize,
124
125    /// Keep-alive timeout in milliseconds
126    pub keep_alive_milliseconds: u64,
127
128    /// User agent String
129    pub user_agent: String,
130
131    /// Whether to use HTTP/2
132    pub use_http2: bool,
133
134    /// Retry configuration
135    pub retry: RetryStrategy,
136}
137
138/// REST API retry strategy
139#[derive(Debug, Clone)]
140pub struct RetryStrategy {
141    /// Whether to attempt retries for failed requests
142    pub enabled: bool,
143
144    /// Maximum number of retry attempts
145    pub max_attempts: u32,
146
147    /// Initial backoff delay in milliseconds
148    pub backoff_initial_milliseconds: u64,
149
150    /// Maximum backoff delay in milliseconds
151    pub backoff_max_milliseconds: u64,
152
153    /// Backoff multiplier (e.g., 2.0 = exponential backoff)
154    pub backoff_multiplier: f64,
155
156    /// HTTP status codes that should trigger a retry
157    pub retry_status_codes: SmallVec<[u16; 8]>,
158}
159
160impl Default for RetryStrategy {
161    fn default() -> Self {
162        Self {
163            enabled: true,
164            max_attempts: 3,
165            backoff_initial_milliseconds: 100,
166            backoff_max_milliseconds: 2000,
167            backoff_multiplier: 2.0,
168            retry_status_codes: SmallVec::from_slice(&[429, 500, 502, 503, 504]),
169        }
170    }
171}
172
173impl Default for RestApiConfig {
174    fn default() -> Self {
175        Self {
176            base_url: String::from(""),
177            timeout_milliseconds: 5000, // 5 seconds default
178            connection_pool_size: 10,
179            keep_alive_milliseconds: 30000, // 30 seconds
180            user_agent: "RustyHFT/1.0".into(),
181            use_http2: true,
182            retry: RetryStrategy::default(),
183        }
184    }
185}
186
187/// Authentication configuration
188#[derive(Debug, Clone, Default)]
189pub struct AuthConfig {
190    /// API key for authentication
191    pub api_key: Option<String>,
192
193    /// Secret key for authentication
194    pub secret_key: Option<String>,
195
196    /// Passphrase (required by some exchanges)
197    pub passphrase: Option<String>,
198
199    /// Whether to use authentication (optional flag)
200    pub use_auth: bool,
201}
202
203/// Cache-line aligned connection configuration for exchange providers
204/// Optimized for performance with minimal cache misses
205#[derive(Debug, Clone)]
206#[repr(align(64))] // Cache-line alignment for better CPU cache efficiency
207pub struct ConnectionConfig {
208    /// WebSocket configuration
209    pub websocket_config: WebSocketConfig,
210
211    /// REST API configuration
212    pub rest_config: RestApiConfig,
213
214    /// Authentication configuration
215    pub auth_config: AuthConfig,
216
217    /// Shared clock instance for time synchronization
218    pub clock: Clock,
219
220    /// Default timestamp format for this exchange (used for automatic conversions)
221    pub timestamp_format: TimestampFormat,
222
223    /// Timestamp cache for frequent timestamp conversions
224    pub timestamp_cache: Arc<RwLock<TimestampCache>>,
225}
226
227impl Default for ConnectionConfig {
228    fn default() -> Self {
229        Self {
230            websocket_config: WebSocketConfig::default(),
231            rest_config: RestApiConfig::default(),
232            auth_config: AuthConfig::default(),
233            clock: Clock::new(),
234            timestamp_format: TimestampFormat::Milliseconds, // Most exchanges use milliseconds
235            timestamp_cache: Arc::new(RwLock::new(TimestampCache::new())),
236        }
237    }
238}