Skip to main content

rnacos/naming/
model.rs

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    //本节点管理的实例设置为0
30    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        //grpc 不走过期检查
49        self.ephemeral && !self.from_grpc && !self.is_from_cluster()
50    }
51
52    pub fn generate_key(&mut self) {
53        //self.id = format!("{}#{}#{}#{}#{}",&self.ip,&self.port,&self.cluster_name,&self.service_name,&self.group_name)
54        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(&self.namespace_id,&self.group_name,&self.service_name)
85        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    /// 转换为 InstanceDo 用于 protobuf 序列化
114    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    /// 从 InstanceDo 创建 Instance
136    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    //pub metadata:Option<HashMap<String,String>>,
212}
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    ///更新其它节点元信息
368    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;