1use serde::{Deserialize, Serialize};
2use std::collections::HashSet;
3use std::{collections::HashMap, sync::Arc};
4
5use crate::common::pb::data_object::InstanceDo;
6use crate::naming::NamingUtils;
7use crate::now_millis_i64;
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct Instance {
12 pub id: Arc<String>,
13 pub ip: Arc<String>,
14 pub port: u32,
15 pub weight: f32,
16 pub enabled: bool,
17 pub healthy: bool,
18 pub ephemeral: bool,
19 pub cluster_name: String,
20 pub service_name: Arc<String>,
21 pub group_name: Arc<String>,
22 pub group_service: Arc<String>,
23 pub metadata: Arc<HashMap<String, String>>,
24 pub last_modified_millis: i64,
25 pub register_time: i64,
26 pub namespace_id: Arc<String>,
27 pub app_name: String,
28 pub from_grpc: bool,
29 pub from_cluster: u64,
31 pub client_id: Arc<String>,
32}
33
34impl Instance {
35 pub fn new(ip: String, port: u32) -> Self {
36 Self {
37 ip: Arc::new(ip),
38 port,
39 ..Default::default()
40 }
41 }
42
43 pub fn is_from_cluster(&self) -> bool {
44 self.from_cluster > 0
45 }
46
47 pub fn is_enable_timeout(&self) -> bool {
48 self.ephemeral && !self.from_grpc && !self.is_from_cluster()
50 }
51
52 pub fn generate_key(&mut self) {
53 self.id = Arc::new(format!("{}#{}", &self.ip, &self.port))
55 }
56
57 pub fn init(&mut self) {
58 self.last_modified_millis = now_millis_i64();
59 if self.id.is_empty() {
60 self.generate_key();
61 }
62 }
63
64 pub fn check_valid(&self) -> bool {
65 if self.id.is_empty()
66 && self.port == 0
67 && self.service_name.is_empty()
68 && self.cluster_name.is_empty()
69 {
70 return false;
71 }
72 true
73 }
74
75 pub fn update_info(&self, o: &Self, _tag: Option<InstanceUpdateTag>) -> bool {
76 self.enabled != o.enabled
77 || self.healthy != o.healthy
78 || self.weight != o.weight
79 || self.ephemeral != o.ephemeral
80 || self.metadata != o.metadata
81 }
82
83 pub fn get_service_key(&self) -> ServiceKey {
84 ServiceKey::new_by_arc(
86 self.namespace_id.clone(),
87 self.group_name.clone(),
88 self.service_name.clone(),
89 )
90 }
91
92 pub fn get_short_key(&self) -> InstanceShortKey {
93 InstanceShortKey {
94 ip: self.ip.clone(),
95 port: self.port.to_owned(),
96 }
97 }
98
99 pub fn get_instance_key(&self) -> InstanceKey {
100 InstanceKey {
101 namespace_id: self.namespace_id.clone(),
102 group_name: self.group_name.clone(),
103 service_name: self.service_name.clone(),
104 ip: self.ip.clone(),
105 port: self.port.to_owned(),
106 }
107 }
108
109 pub fn get_id_string(&self) -> String {
110 format!("{}#{}", &self.ip, &self.port)
111 }
112
113 pub fn to_do(&self) -> InstanceDo<'static> {
115 InstanceDo {
116 ip: self.ip.as_ref().clone().into(),
117 port: self.port,
118 weight: self.weight,
119 enabled: self.enabled,
120 healthy: self.healthy,
121 ephemeral: self.ephemeral,
122 metadata: self
123 .metadata
124 .iter()
125 .map(|(k, v)| (k.clone().into(), v.clone().into()))
126 .collect(),
127 namespace_id: self.namespace_id.as_ref().clone().into(),
128 group_name: self.group_name.as_ref().clone().into(),
129 service_name: self.service_name.as_ref().clone().into(),
130 cluster_name: self.cluster_name.clone().into(),
131 app_name: self.app_name.clone().into(),
132 }
133 }
134
135 pub fn from_do(instance_do: InstanceDo) -> Self {
137 let service_name = instance_do.service_name.clone().into_owned();
138 let group_name = instance_do.group_name.clone().into_owned();
139 Instance {
140 id: Arc::new(format!("{}#{}", instance_do.ip, instance_do.port)),
141 ip: Arc::new(instance_do.ip.into_owned()),
142 port: instance_do.port,
143 weight: instance_do.weight,
144 enabled: instance_do.enabled,
145 healthy: instance_do.healthy,
146 ephemeral: instance_do.ephemeral,
147 cluster_name: instance_do.cluster_name.into_owned(),
148 service_name: Arc::new(service_name.clone()),
149 group_name: Arc::new(group_name.clone()),
150 group_service: Arc::new(NamingUtils::get_group_and_service_name(
151 &service_name,
152 &group_name,
153 )),
154 metadata: Arc::new(
155 instance_do
156 .metadata
157 .into_iter()
158 .map(|(k, v)| (k.into_owned(), v.into_owned()))
159 .collect(),
160 ),
161 last_modified_millis: now_millis_i64(),
162 register_time: now_millis_i64(),
163 namespace_id: Arc::new(instance_do.namespace_id.into_owned()),
164 app_name: instance_do.app_name.into_owned(),
165 from_grpc: false,
166 from_cluster: 0,
167 client_id: Arc::new(String::new()),
168 }
169 }
170}
171
172impl Default for Instance {
173 fn default() -> Self {
174 Self {
175 id: Default::default(),
176 ip: Default::default(),
177 port: Default::default(),
178 weight: 1f32,
179 enabled: true,
180 healthy: true,
181 ephemeral: true,
182 cluster_name: "DEFAULT".to_owned(),
183 service_name: Default::default(),
184 group_name: Default::default(),
185 group_service: Default::default(),
186 metadata: Default::default(),
187 last_modified_millis: Default::default(),
188 register_time: now_millis_i64(),
189 namespace_id: Default::default(),
190 app_name: Default::default(),
191 from_grpc: false,
192 from_cluster: 0,
193 client_id: Default::default(),
194 }
195 }
196}
197
198#[derive(Debug, Serialize, Deserialize, Default, Clone)]
199#[serde(rename_all = "camelCase")]
200pub struct ServiceInfo {
201 pub name: Option<Arc<String>>,
202 pub group_name: Option<Arc<String>>,
203 pub clusters: Option<String>,
204 pub cache_millis: i64,
205 pub hosts: Option<Vec<Arc<Instance>>>,
206 pub last_ref_time: i64,
207 pub checksum: i64,
208 #[serde(rename = "allIPs")]
209 pub all_ips: bool,
210 pub reach_protection_threshold: bool,
211 }
213
214#[derive(Debug, Serialize, Deserialize, Default, Clone)]
215#[serde(rename_all = "camelCase")]
216pub struct ServiceDetailDto {
217 pub namespace_id: Arc<String>,
218 pub service_name: Arc<String>,
219 pub group_name: Arc<String>,
220 pub metadata: Option<Arc<HashMap<String, String>>>,
221 pub protect_threshold: Option<f32>,
222 pub grpc_instance_count: Option<i32>,
223}
224
225impl ServiceDetailDto {
226 pub(crate) fn to_service_key(&self) -> ServiceKey {
227 ServiceKey::new_by_arc(
228 self.namespace_id.clone(),
229 self.group_name.clone(),
230 self.service_name.clone(),
231 )
232 }
233}
234
235#[derive(Debug, Serialize, Deserialize, Clone)]
236pub struct InstanceUpdateTag {
237 pub weight: bool,
238 pub metadata: bool,
239 pub enabled: bool,
240 pub ephemeral: bool,
241 pub from_update: bool,
242}
243
244impl InstanceUpdateTag {
245 pub fn is_al(&self) -> bool {
246 self.weight && self.metadata && self.enabled && self.ephemeral
247 }
248 pub fn is_none(&self) -> bool {
249 !self.weight && !self.metadata && !self.enabled && !self.ephemeral
250 }
251}
252
253impl Default for InstanceUpdateTag {
254 fn default() -> Self {
255 Self {
256 weight: true,
257 metadata: true,
258 enabled: true,
259 ephemeral: true,
260 from_update: false,
261 }
262 }
263}
264
265#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, PartialOrd, Ord)]
266pub struct ServiceKey {
267 pub namespace_id: Arc<String>,
268 pub group_name: Arc<String>,
269 pub service_name: Arc<String>,
270}
271
272impl ServiceKey {
273 pub fn new(namespace_id: &str, group_name: &str, service_name: &str) -> Self {
274 Self {
275 namespace_id: Arc::new(namespace_id.to_owned()),
276 group_name: Arc::new(group_name.to_owned()),
277 service_name: Arc::new(service_name.to_owned()),
278 }
279 }
280
281 pub fn new_by_arc(
282 namespace_id: Arc<String>,
283 group_name: Arc<String>,
284 service_name: Arc<String>,
285 ) -> Self {
286 Self {
287 namespace_id,
288 group_name,
289 service_name,
290 }
291 }
292
293 pub fn get_join_service_name(&self) -> String {
294 format!("{}@@{}", self.group_name, self.service_name)
295 }
296}
297
298#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Serialize, Deserialize)]
299#[serde(rename_all = "camelCase")]
300pub struct InstanceKey {
301 pub namespace_id: Arc<String>,
302 pub group_name: Arc<String>,
303 pub service_name: Arc<String>,
304 pub ip: Arc<String>,
305 pub port: u32,
306}
307
308impl InstanceKey {
309 pub fn new_by_service_key(key: &ServiceKey, ip: Arc<String>, port: u32) -> Self {
310 Self {
311 namespace_id: key.namespace_id.clone(),
312 group_name: key.group_name.clone(),
313 service_name: key.service_name.clone(),
314 ip,
315 port,
316 }
317 }
318
319 pub fn get_service_key(&self) -> ServiceKey {
320 ServiceKey::new_by_arc(
321 self.namespace_id.clone(),
322 self.group_name.clone(),
323 self.service_name.clone(),
324 )
325 }
326
327 pub fn get_short_key(&self) -> InstanceShortKey {
328 InstanceShortKey {
329 ip: self.ip.clone(),
330 port: self.port.to_owned(),
331 }
332 }
333}
334
335#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Serialize, Deserialize, Ord, PartialOrd)]
336#[serde(rename_all = "camelCase")]
337pub struct InstanceShortKey {
338 pub ip: Arc<String>,
339 pub port: u32,
340}
341
342impl InstanceShortKey {
343 pub fn new(ip: Arc<String>, port: u32) -> Self {
344 Self { ip, port }
345 }
346
347 pub fn new_from_instance_id(id: &str) -> Self {
348 let items: Vec<&str> = id.split('#').collect();
349 assert!(items.len() > 1);
350 let ip_str = items[0];
351 let port_str = items[1];
352 let port: u32 = port_str.parse().unwrap_or_default();
353 Self {
354 ip: Arc::new(ip_str.to_owned()),
355 port,
356 }
357 }
358}
359
360#[derive(Debug, Clone)]
361pub enum UpdateInstanceType {
362 None,
363 New,
364 Remove,
365 UpdateTime,
366 UpdateValue,
367 UpdateOtherClusterMetaData(u64, Instance),
369}
370
371#[derive(Debug, Clone)]
372pub enum UpdatePerpetualType {
373 None,
374 New,
375 Update,
376 Remove,
377}
378
379#[derive(Debug, Clone)]
380pub enum DistroData {
381 ClientInstances(HashMap<Arc<String>, HashSet<InstanceKey>>),
382 #[deprecated]
383 ServiceInstanceCount(HashMap<ServiceKey, u64>),
384 DiffClientInstances(Vec<InstanceKey>),
385}
386
387pub mod actor_model;