nautilus_data/engine/
registry.rs1use super::{
17 AHashSet, ClientId, DataClientAdapter, DataEngine, FAILED, Venue, check_key_in_map,
18 check_key_not_in_map, check_predicate_true,
19};
20
21impl DataEngine {
22 #[must_use]
23 pub(crate) fn is_external_client(&self, client_id: ClientId) -> bool {
24 self.cache.borrow().is_external_data_client(&client_id)
25 }
26
27 pub fn register_client(&mut self, mut client: DataClientAdapter, routing: Option<Venue>) {
34 client.is_stopped = self.is_stopped;
35 let client_id = client.client_id();
36
37 check_key_not_in_map(&client_id, &self.clients, "client_id", "clients").expect(FAILED);
38
39 if let Some(routing) = routing {
40 self.routing_map.insert(routing, client_id);
41 log::debug!("Set client {client_id} routing for {routing}");
42 }
43
44 if client.venue.is_none() && self.default_client_id.is_none() {
45 self.default_client_id = Some(client_id);
46 log::debug!("Registered client {client_id} for default routing");
47 }
48
49 self.clients.insert(client_id, client);
50 log::debug!("Registered client {client_id}");
51 }
52
53 pub fn deregister_client(&mut self, client_id: &ClientId) {
59 check_key_in_map(client_id, &self.clients, "client_id", "clients").expect(FAILED);
60
61 if self.default_client_id.as_ref() == Some(client_id) {
62 self.default_client_id = None;
63 }
64
65 self.clients.shift_remove(client_id);
66 log::info!("Deregistered client {client_id}");
67 }
68
69 pub fn register_default_client(&mut self, mut client: DataClientAdapter) {
81 client.is_stopped = self.is_stopped;
82 check_predicate_true(
83 self.default_client_id.is_none(),
84 "default client already registered",
85 )
86 .expect(FAILED);
87
88 let client_id = client.client_id();
89 self.clients.insert(client_id, client);
90 self.default_client_id = Some(client_id);
91 log::debug!("Registered default client {client_id}");
92 }
93
94 pub fn set_default_client(&mut self, client_id: ClientId) -> anyhow::Result<()> {
101 if self.default_client_id.is_some_and(|id| id != client_id) {
102 anyhow::bail!("default client already registered");
103 }
104
105 if !self.clients.contains_key(&client_id) {
106 anyhow::bail!("No client registered with ID {client_id}");
107 }
108
109 self.default_client_id = Some(client_id);
110 log::debug!("Set client {client_id} as default");
111 Ok(())
112 }
113
114 pub fn register_venue_routing(
121 &mut self,
122 client_id: ClientId,
123 venue: Venue,
124 ) -> anyhow::Result<()> {
125 if !self.clients.contains_key(&client_id) {
126 anyhow::bail!("No client registered with ID {client_id}");
127 }
128
129 if let Some(existing_client_id) = self.routing_map.get(&venue)
130 && *existing_client_id != client_id
131 {
132 anyhow::bail!(
133 "Venue {venue} already routed to {existing_client_id}, \
134 cannot re-route to {client_id}"
135 );
136 }
137
138 self.routing_map.insert(venue, client_id);
139 log::debug!("Set client {client_id} routing for {venue}");
140 Ok(())
141 }
142
143 #[must_use]
145 pub fn client_connection_status(&self) -> Vec<(ClientId, bool)> {
146 self.get_clients()
147 .into_iter()
148 .map(|client| (client.client_id(), client.is_connected()))
149 .collect()
150 }
151
152 #[must_use]
154 pub fn registered_clients(&self) -> Vec<ClientId> {
155 self.get_clients()
156 .into_iter()
157 .map(|client| client.client_id())
158 .collect()
159 }
160
161 pub(crate) fn collect_subscriptions<F, T>(&self, get_subs: F) -> Vec<T>
162 where
163 F: Fn(&DataClientAdapter) -> &AHashSet<T>,
164 T: Clone,
165 {
166 self.get_clients()
167 .into_iter()
168 .flat_map(get_subs)
169 .cloned()
170 .collect()
171 }
172
173 #[must_use]
174 pub fn get_clients(&self) -> Vec<&DataClientAdapter> {
175 self.clients.values().collect()
176 }
177
178 #[must_use]
179 pub fn get_clients_mut(&mut self) -> Vec<&mut DataClientAdapter> {
180 self.clients.values_mut().collect()
181 }
182
183 pub fn get_client(
184 &mut self,
185 client_id: Option<&ClientId>,
186 venue: Option<&Venue>,
187 ) -> Option<&mut DataClientAdapter> {
188 if let Some(client_id) = client_id {
189 return self.clients.get_mut(client_id);
190 }
191
192 if let Some(v) = venue
193 && let Some(client_id) = self.routing_map.get(v)
194 {
195 return self.clients.get_mut(client_id);
196 }
197
198 self.get_default_client()
199 }
200
201 pub(super) fn get_command_client(
206 &mut self,
207 client_id: Option<&ClientId>,
208 venue: Option<&Venue>,
209 ) -> Option<&mut DataClientAdapter> {
210 let backtest_id = ClientId::new("BACKTEST");
211 if self.clients.contains_key(&backtest_id) {
212 return self.clients.get_mut(&backtest_id);
213 }
214
215 self.get_client(client_id, venue)
216 }
217
218 fn get_default_client(&mut self) -> Option<&mut DataClientAdapter> {
219 match self.default_client_id {
220 Some(id) => self.clients.get_mut(&id),
221 None => None,
222 }
223 }
224}