futu_server/subscription/
push_regs.rs1use futu_core::qot_stock_key::QotSecurityKey;
2use futu_qot::subscription_plan::is_kl_sub_type;
3
4use super::SubscriptionManager;
5
6impl SubscriptionManager {
7 pub fn register_push_broker(
13 &self,
14 conn_id: u64,
15 sec_key: &QotSecurityKey,
16 sub_type: i32,
17 rehab_type: i32,
18 ) {
19 self.register_push_inner(conn_id, Self::broker_key(sec_key), sub_type, rehab_type)
20 }
21
22 fn register_push_inner(
23 &self,
24 conn_id: u64,
25 key: QotSecurityKey,
26 sub_type: i32,
27 rehab_type: i32,
28 ) {
29 let effective_rehab = if is_kl_sub_type(sub_type) {
30 rehab_type
31 } else {
32 0
33 };
34 let cache_key = key.cache_key();
35 let mut regs = self.qot_push_regs.write();
36 regs.by_tuple
37 .entry((key, sub_type, effective_rehab))
38 .or_default()
39 .insert(conn_id);
40 regs.qot_push_regs_by_cache_key
41 .entry(cache_key)
42 .or_default()
43 .entry((sub_type, effective_rehab))
44 .or_default()
45 .insert(conn_id);
46 }
47
48 pub fn unregister_push_broker(
50 &self,
51 conn_id: u64,
52 sec_key: &QotSecurityKey,
53 sub_type: i32,
54 rehab_type: i32,
55 ) {
56 self.unregister_push_inner(conn_id, Self::broker_key(sec_key), sub_type, rehab_type)
57 }
58
59 fn unregister_push_inner(
60 &self,
61 conn_id: u64,
62 key: QotSecurityKey,
63 sub_type: i32,
64 rehab_type: i32,
65 ) {
66 let effective_rehab = if is_kl_sub_type(sub_type) {
67 rehab_type
68 } else {
69 0
70 };
71 let cache_key = key.cache_key();
72 let map_key = (key, sub_type, effective_rehab);
73 let mut regs = self.qot_push_regs.write();
74 if let Some(set) = regs.by_tuple.get_mut(&map_key) {
75 set.remove(&conn_id);
76 if set.is_empty() {
77 regs.by_tuple.remove(&map_key);
78 }
79 }
80 if let Some(by_sub) = regs.qot_push_regs_by_cache_key.get_mut(&cache_key) {
81 if let Some(set) = by_sub.get_mut(&(sub_type, effective_rehab)) {
82 set.remove(&conn_id);
83 if set.is_empty() {
84 by_sub.remove(&(sub_type, effective_rehab));
85 }
86 }
87 if by_sub.is_empty() {
88 regs.qot_push_regs_by_cache_key.remove(&cache_key);
89 }
90 }
91 }
92
93 pub fn get_qot_push_subscribers_broker(
96 &self,
97 sec_key: &QotSecurityKey,
98 sub_type: i32,
99 rehab_type: i32,
100 ) -> Vec<u64> {
101 self.get_qot_push_subscribers_inner(Self::broker_key(sec_key), sub_type, rehab_type)
102 }
103
104 pub fn get_qot_push_subscribers_by_cache_key(
111 &self,
112 cache_key: &str,
113 sub_type: i32,
114 rehab_type: i32,
115 ) -> Vec<u64> {
116 let effective_rehab = if is_kl_sub_type(sub_type) {
117 rehab_type
118 } else {
119 0
120 };
121 let regs = self.qot_push_regs.read();
122 let mut out: Vec<u64> = regs
123 .qot_push_regs_by_cache_key
124 .get(cache_key)
125 .and_then(|by_sub| by_sub.get(&(sub_type, effective_rehab)))
126 .map_or_else(Vec::new, |subscribers| {
127 subscribers.iter().copied().collect()
128 });
129
130 out.sort_unstable();
131 out.dedup();
132 out
133 }
134
135 fn get_qot_push_subscribers_inner(
136 &self,
137 key: QotSecurityKey,
138 sub_type: i32,
139 rehab_type: i32,
140 ) -> Vec<u64> {
141 let effective_rehab = if is_kl_sub_type(sub_type) {
142 rehab_type
143 } else {
144 0
145 };
146 match self
147 .qot_push_regs
148 .read()
149 .by_tuple
150 .get(&(key, sub_type, effective_rehab))
151 {
152 Some(subscribers) => subscribers.iter().copied().collect(),
153 None => Vec::new(),
154 }
155 }
156
157 pub fn is_push_registered_any_rehab_broker(
159 &self,
160 conn_id: u64,
161 sec_key: &QotSecurityKey,
162 sub_type: i32,
163 ) -> bool {
164 let broker_key = Self::broker_key(sec_key);
165 let pr = self.qot_push_regs.read();
166 pr.by_tuple.iter().any(|((k, st, _rehab), set)| {
167 k == &broker_key && *st == sub_type && set.contains(&conn_id)
168 })
169 }
170}