1use std::fmt::{self, Debug};
2use std::future;
3use std::hash::Hash;
4use std::sync::Arc;
5use std::time::Duration;
6
7use bytes::Bytes;
8use futures_util::{FutureExt, TryFutureExt};
9use tracing::Instrument;
10
11use acktor::{
12 Address, Message, Recipient, SendError, Sender, SenderId,
13 address::{ClosedResultFuture, DoSendResult, DoSendResultFuture, SendResult, SendResultFuture},
14 channel::oneshot,
15};
16
17use crate::codec::{Decode, DecodeContext, Encode, EncodeContext};
18use crate::remote_actor::RemoteActorRegistry;
19use crate::remote_message::RemoteMessage;
20use crate::session::Session;
21
22pub struct RemoteAddress {
31 index: u64,
33 remote_actor_id: u64,
35 session: Address<Session>,
38 encode_context: EncodeContext,
40}
41
42impl Debug for RemoteAddress {
43 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44 f.debug_tuple("RemoteAddress")
45 .field(&self.session.index())
46 .field(&self.remote_actor_id)
47 .finish()
48 }
49}
50
51impl Clone for RemoteAddress {
52 #[inline]
53 fn clone(&self) -> Self {
54 Self {
55 index: self.index,
56 remote_actor_id: self.remote_actor_id,
57 session: self.session.clone(),
58 encode_context: self.encode_context.clone(),
59 }
60 }
61}
62
63impl PartialEq for RemoteAddress {
64 #[inline]
65 fn eq(&self, other: &Self) -> bool {
66 self.remote_actor_id == other.remote_actor_id
67 && self.session.index() == other.session.index()
68 }
69}
70
71impl Eq for RemoteAddress {}
72
73impl Hash for RemoteAddress {
74 #[inline]
75 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
76 self.index.hash(state)
77 }
78}
79
80impl RemoteAddress {
81 pub const REMOTE_FLAG: u64 = 1 << 63;
84
85 pub fn new(
97 remote_actor_id: u64,
98 session: Address<Session>,
99 registry: RemoteActorRegistry,
100 ) -> Self {
101 let index = Self::REMOTE_FLAG | ((session.index().reverse_bits() >> 1) ^ remote_actor_id);
102 Self {
103 index,
104 remote_actor_id,
105 session,
106 encode_context: EncodeContext::new(registry),
107 }
108 }
109
110 fn decode_context(&self) -> DecodeContext {
111 self.encode_context
112 .create_decode_context(self.session.clone())
113 }
114
115 pub fn closed(&self) -> impl Future<Output = ()> + Send {
117 self.session.closed()
118 }
119
120 pub fn is_closed(&self) -> bool {
122 self.session.is_closed()
123 }
124
125 pub fn capacity(&self) -> usize {
127 self.session.capacity()
128 }
129}
130
131async fn decode_and_forward<M>(
132 raw_rx: oneshot::Receiver<Bytes>,
133 tx: oneshot::Sender<M::Result>,
134 decode_context: DecodeContext,
135) where
136 M: Message + Encode,
137 M::Result: Decode,
138{
139 let decode_result = match raw_rx.await {
140 Ok(bytes) => M::Result::decode(bytes, Some(&decode_context)),
141 Err(e) => {
142 let _ = tx.send_err(e);
143 return;
144 }
145 };
146
147 match decode_result {
148 Ok(result) => {
149 let _ = tx.send(result);
150 }
151 Err(e) => {
152 let _ = tx.send_err(e);
153 }
154 }
155}
156
157impl SenderId for RemoteAddress {
158 #[inline]
159 fn index(&self) -> u64 {
160 self.index
161 }
162}
163
164impl<M> Sender<M> for RemoteAddress
165where
166 M: Message + Encode,
167 M::Result: Decode,
168{
169 fn closed(&self) -> ClosedResultFuture<'_> {
170 self.closed().boxed()
171 }
172
173 fn is_closed(&self) -> bool {
174 self.is_closed()
175 }
176
177 fn capacity(&self) -> usize {
178 self.capacity()
179 }
180
181 fn send(&self, msg: M) -> SendResultFuture<'_, M> {
182 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
183 Ok(bytes) => bytes,
184 Err(e) => return future::ready(Err(SendError::other(e, msg))).boxed(),
185 };
186
187 let (raw_tx, raw_rx) = oneshot::channel::<Bytes>();
188 let (tx, rx) = oneshot::channel::<M::Result>();
189
190 let decode_context = self.decode_context();
191
192 tokio::spawn(
193 async move {
194 decode_and_forward::<M>(raw_rx, tx, decode_context).await;
195 }
196 .in_current_span(),
197 );
198
199 self.session
203 .do_send(RemoteMessage::send(
204 self.remote_actor_id,
205 <M as Encode>::ID,
206 message_bytes,
207 raw_tx,
208 ))
209 .map(|result| match result {
212 Ok(_) => Ok(rx),
213 Err(_) => Err(SendError::Closed(msg)),
214 })
215 .boxed()
216 }
217
218 fn do_send(&self, msg: M) -> DoSendResultFuture<'_, M> {
219 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
220 Ok(bytes) => bytes,
221 Err(e) => return future::ready(Err(SendError::other(e, msg))).boxed(),
222 };
223
224 self.session
228 .do_send(RemoteMessage::do_send(
229 self.remote_actor_id,
230 <M as Encode>::ID,
231 message_bytes,
232 ))
233 .map_err(|_| SendError::Closed(msg))
236 .boxed()
237 }
238
239 fn try_send(&self, msg: M) -> SendResult<M> {
240 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
241 Ok(bytes) => bytes,
242 Err(e) => return Err(SendError::other(e, msg)),
243 };
244
245 let (raw_tx, raw_rx) = oneshot::channel::<Bytes>();
246 let (tx, rx) = oneshot::channel::<M::Result>();
247
248 let decode_context = self.decode_context();
249
250 tokio::spawn(
251 async move {
252 decode_and_forward::<M>(raw_rx, tx, decode_context).await;
253 }
254 .in_current_span(),
255 );
256
257 match self.session.try_do_send(RemoteMessage::send(
258 self.remote_actor_id,
259 <M as Encode>::ID,
260 message_bytes,
261 raw_tx,
262 )) {
263 Ok(_) => Ok(rx),
264 Err(e) => match e {
265 SendError::Full(_) => Err(SendError::Full(msg)),
266 _ => Err(SendError::Closed(msg)),
267 },
268 }
269 }
270
271 fn try_do_send(&self, msg: M) -> DoSendResult<M> {
272 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
273 Ok(bytes) => bytes,
274 Err(e) => return Err(SendError::other(e, msg)),
275 };
276
277 self.session
278 .try_do_send(RemoteMessage::do_send(
279 self.remote_actor_id,
280 <M as Encode>::ID,
281 message_bytes,
282 ))
283 .map_err(|e| match e {
284 SendError::Full(_) => SendError::Full(msg),
285 _ => SendError::Closed(msg),
286 })
287 }
288
289 fn send_timeout(&self, msg: M, timeout: Duration) -> SendResultFuture<'_, M> {
290 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
291 Ok(bytes) => bytes,
292 Err(e) => return future::ready(Err(SendError::other(e, msg))).boxed(),
293 };
294
295 let (raw_tx, raw_rx) = oneshot::channel::<Bytes>();
296 let (tx, rx) = oneshot::channel::<M::Result>();
297
298 let decode_context = self.decode_context();
299
300 tokio::spawn(
301 async move {
302 decode_and_forward::<M>(raw_rx, tx, decode_context).await;
303 }
304 .in_current_span(),
305 );
306
307 self.session
311 .do_send_timeout(
312 RemoteMessage::send(
313 self.remote_actor_id,
314 <M as Encode>::ID,
315 message_bytes,
316 raw_tx,
317 ),
318 timeout,
319 )
320 .map(|result| match result {
323 Ok(_) => Ok(rx),
324 Err(_) => Err(SendError::Closed(msg)),
325 })
326 .boxed()
327 }
328
329 fn do_send_timeout(&self, msg: M, timeout: Duration) -> DoSendResultFuture<'_, M> {
330 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
331 Ok(bytes) => bytes,
332 Err(e) => return future::ready(Err(SendError::other(e, msg))).boxed(),
333 };
334
335 self.session
339 .do_send_timeout(
340 RemoteMessage::do_send(self.remote_actor_id, <M as Encode>::ID, message_bytes),
341 timeout,
342 )
343 .map_err(|_| SendError::Closed(msg))
346 .boxed()
347 }
348
349 fn blocking_send(&self, msg: M) -> SendResult<M> {
350 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
351 Ok(bytes) => bytes,
352 Err(e) => return Err(SendError::other(e, msg)),
353 };
354
355 let (raw_tx, raw_rx) = oneshot::channel::<Bytes>();
356 let (tx, rx) = oneshot::channel::<M::Result>();
357
358 let decode_context = self.decode_context();
359
360 tokio::spawn(
361 async move {
362 decode_and_forward::<M>(raw_rx, tx, decode_context).await;
363 }
364 .in_current_span(),
365 );
366
367 match self.session.blocking_do_send(RemoteMessage::send(
368 self.remote_actor_id,
369 <M as Encode>::ID,
370 message_bytes,
371 raw_tx,
372 )) {
373 Ok(_) => Ok(rx),
374 Err(_) => Err(SendError::Closed(msg)),
375 }
376 }
377
378 fn blocking_do_send(&self, msg: M) -> DoSendResult<M> {
379 let message_bytes = match msg.encode_to_bytes(Some(&self.encode_context)) {
380 Ok(bytes) => bytes,
381 Err(e) => return Err(SendError::other(e, msg)),
382 };
383
384 self.session
385 .blocking_do_send(RemoteMessage::do_send(
386 self.remote_actor_id,
387 <M as Encode>::ID,
388 message_bytes,
389 ))
390 .map_err(|_| SendError::Closed(msg))
391 }
392}
393
394impl<M> From<RemoteAddress> for Recipient<M>
395where
396 M: Message + Encode,
397 M::Result: Decode,
398{
399 fn from(address: RemoteAddress) -> Self {
400 Recipient::new(Arc::new(address))
401 }
402}