actix_telepathy/remote/addr/
resolver.rs1use crate::remote::RemoteWrapper;
2use actix::prelude::*;
3use log::*;
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::fmt::{self, Debug, Display, Formatter};
7use std::hash::{Hash, Hasher};
8use std::str::FromStr;
9
10const NETWORKINTERFACE: &str = "networkinterface";
11const GOSSIP: &str = "gossip";
12
13#[derive(Serialize, Deserialize, Debug)]
14pub enum AddrRepresentation {
15 NetworkInterface,
16 Connector,
17 Key(String),
18}
19
20impl Display for AddrRepresentation {
21 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22 match self {
23 AddrRepresentation::NetworkInterface => f.write_str(NETWORKINTERFACE),
24 AddrRepresentation::Connector => f.write_str(GOSSIP),
25 AddrRepresentation::Key(id) => f.write_str(id),
26 }
27 }
28}
29
30impl FromStr for AddrRepresentation {
31 type Err = ();
32
33 fn from_str(s: &str) -> Result<Self, Self::Err> {
34 Ok(match s {
35 NETWORKINTERFACE => AddrRepresentation::NetworkInterface,
36 GOSSIP => AddrRepresentation::Connector,
37 _ => AddrRepresentation::Key(String::from(s)),
38 })
39 }
40}
41
42impl Clone for AddrRepresentation {
43 fn clone(&self) -> Self {
44 AddrRepresentation::from_str(&self.to_string()).unwrap()
45 }
46}
47
48impl PartialEq for AddrRepresentation {
49 fn eq(&self, other: &Self) -> bool {
50 let self_key = self.to_string();
51 (self_key == other.to_string() && self_key != "Key")
52 || (self_key == "Key"
53 && match self {
54 AddrRepresentation::Key(key) => match other {
55 AddrRepresentation::Key(other_key) => key == other_key,
56 _ => false,
57 },
58 _ => false,
59 })
60 }
61}
62
63impl Eq for AddrRepresentation {}
64
65impl Hash for AddrRepresentation {
66 fn hash<H: Hasher>(&self, state: &mut H) {
67 self.to_string().hash(state);
68 }
69}
70
71#[derive(Message)]
72#[rtype(result = "Result<AddrResponse, ()>")]
73pub enum AddrRequest {
74 Register(Recipient<RemoteWrapper>, String),
75 ResolveStr(String),
76 ResolveRec(Recipient<RemoteWrapper>),
77}
78
79pub enum AddrResponse {
80 Register,
81 ResolveStr(Recipient<RemoteWrapper>),
82 ResolveRec(String),
83}
84
85#[derive(Default)]
86pub struct AddrResolver {
87 str2rec: HashMap<String, Recipient<RemoteWrapper>>,
88 rec2str: HashMap<Recipient<RemoteWrapper>, String>,
89}
90
91pub struct NotAvailableError {}
92
93impl Debug for NotAvailableError {
94 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
95 f.debug_struct("NotAvailableError").finish()
96 }
97}
98
99impl AddrResolver {
102 pub fn new() -> Self {
103 AddrResolver::default()
104 }
105
106 pub fn resolve_str(
107 &mut self,
108 id: String,
109 ) -> Result<&Recipient<RemoteWrapper>, NotAvailableError> {
110 match self.str2rec.get(&id) {
111 Some(rec) => Ok(rec),
112 None => {
113 error!("ID {} is not registered", id);
114 Err(NotAvailableError {})
115 }
116 }
117 }
118
119 pub fn resolve_rec(
120 &mut self,
121 rec: &Recipient<RemoteWrapper>,
122 ) -> Result<&String, NotAvailableError> {
123 match self.rec2str.get(rec) {
124 Some(str) => Ok(str),
125 None => {
126 error!("Recipient is not registered");
127 Err(NotAvailableError {})
128 }
129 }
130 }
131
132 pub fn resolve_rec_from_addr_representation(
133 &mut self,
134 addr_representation: AddrRepresentation,
135 ) -> Result<&Recipient<RemoteWrapper>, NotAvailableError> {
136 self.resolve_str(addr_representation.to_string())
137 }
138}
139
140impl Actor for AddrResolver {
141 type Context = Context<Self>;
142
143 fn started(&mut self, _ctx: &mut Context<Self>) {
144 debug!("AddressResolver actor started");
145 }
146}
147
148impl Handler<RemoteWrapper> for AddrResolver {
149 type Result = ();
150
151 fn handle(&mut self, msg: RemoteWrapper, _ctx: &mut Context<Self>) -> Self::Result {
152 if let Ok(recipient) = self.resolve_rec_from_addr_representation(msg.destination.id.clone())
153 {
154 recipient.do_send(msg);
155 } else {
156 warn!(
157 "Could not resolve Recipient '{}' for RemoteMessage. Is this receiver a RemoteActor? Message is abandoned.",
158 msg.identifier
159 );
160 }
161 }
162}
163
164impl Handler<AddrRequest> for AddrResolver {
165 type Result = Result<AddrResponse, ()>;
166
167 fn handle(&mut self, msg: AddrRequest, _ctx: &mut Context<Self>) -> Self::Result {
168 match msg {
169 AddrRequest::Register(rec, identifier) => {
170 let is_new = !self.rec2str.contains_key(&rec);
171
172 if is_new {
173 self.str2rec.insert(identifier.clone(), rec.clone());
174 self.rec2str.insert(rec, identifier.clone());
175 debug!("Actor '{}' registered", identifier);
176 Ok(AddrResponse::Register)
177 } else {
178 debug!("Recipient is already added");
179 Err(())
180 }
181 }
182 AddrRequest::ResolveStr(id) => {
183 let rec = self.resolve_str(id);
184 match rec {
185 Ok(r) => Ok(AddrResponse::ResolveStr((*r).clone())),
186 Err(_) => Err(()),
187 }
188 }
189 AddrRequest::ResolveRec(rec) => {
190 let id = self.resolve_rec(&rec);
191 match id {
192 Ok(i) => Ok(AddrResponse::ResolveRec(i.clone())),
193 Err(_) => Err(()),
194 }
195 }
196 }
197 }
198}
199
200impl Supervised for AddrResolver {}
201impl SystemService for AddrResolver {}