@@ -1082,6 +1082,33 @@ impl Mailbox {
1082
1082
MailboxError :: new ( self . state . actor_id . clone ( ) , err)
1083
1083
}
1084
1084
1085
+ /// Look up the `UnboundedPortSender` for the port associated with
1086
+ /// the message type `M`, as defined by `<M as Named>::port()`.
1087
+ ///
1088
+ /// This performs a dynamic downcast to recover the original
1089
+ /// sender type. Returns `None` if the port is not bound or if the
1090
+ /// type does not match.
1091
+ ///
1092
+ /// # Panics
1093
+ /// Panics in debug mode if the port is bound but the stored
1094
+ /// `port_id` does not match the expected one.
1095
+ pub ( crate ) fn lookup_sender < M : RemoteMessage > ( & self ) -> Option < UnboundedPortSender < M > > {
1096
+ let port_index = M :: port ( ) ;
1097
+ self . state . ports . get ( & port_index) . and_then ( |boxed| {
1098
+ boxed
1099
+ . as_any ( )
1100
+ . downcast_ref :: < UnboundedSender < M > > ( )
1101
+ . map ( |s| {
1102
+ debug_assert_eq ! (
1103
+ s. port_id,
1104
+ self . actor_id( ) . port_id( port_index) ,
1105
+ "port_id mismatch in downcasted UnboundedSender"
1106
+ ) ;
1107
+ s. sender . clone ( )
1108
+ } )
1109
+ } )
1110
+ }
1111
+
1085
1112
fn bind < M : RemoteMessage > ( & self , handle : & PortHandle < M > ) -> PortRef < M > {
1086
1113
assert_eq ! (
1087
1114
handle. mailbox. actor_id( ) ,
@@ -1210,8 +1237,17 @@ impl MailboxSender for Mailbox {
1210
1237
1211
1238
impl cap:: sealed:: CanSend for Mailbox {
1212
1239
fn post ( & self , dest : PortId , data : Serialized ) {
1240
+ let undeliverable_port_id = Undeliverable :: < MessageEnvelope > :: port ( ) ;
1241
+ let return_handle = match self . lookup_sender :: < Undeliverable < MessageEnvelope > > ( ) {
1242
+ Some ( sender) => PortHandle :: new ( self . clone ( ) , undeliverable_port_id, sender) ,
1243
+ None => {
1244
+ let ( handle, _) = self . open_port :: < Undeliverable < MessageEnvelope > > ( ) ;
1245
+ handle. bind_to ( undeliverable_port_id) ;
1246
+ handle
1247
+ }
1248
+ } ;
1213
1249
let envelope = MessageEnvelope :: new ( self . actor_id ( ) . clone ( ) , dest, data) ;
1214
- MailboxSender :: post ( self , envelope, monitored_return_handle ( ) ) ;
1250
+ MailboxSender :: post ( self , envelope, return_handle ) ;
1215
1251
}
1216
1252
}
1217
1253
@@ -1592,6 +1628,8 @@ pub struct SerializedSenderError {
1592
1628
/// - It abstracts over [`Port`]s and [`OncePort`]s, by dynamically tracking the
1593
1629
/// validity of the underlying port.
1594
1630
trait SerializedSender : Send + Sync {
1631
+ fn as_any ( & self ) -> & dyn Any ;
1632
+
1595
1633
/// Send a serialized message. SerializedSender will deserialize the
1596
1634
/// message (failing if it fails to deserialize), and then send the
1597
1635
/// resulting message on the underlying port.
@@ -1603,7 +1641,7 @@ trait SerializedSender: Send + Sync {
1603
1641
}
1604
1642
1605
1643
/// A sender to an M-typed unbounded port.
1606
- enum UnboundedPortSender < M : Message > {
1644
+ pub ( crate ) enum UnboundedPortSender < M : Message > {
1607
1645
/// Send directly to the mpsc queue.
1608
1646
Mpsc ( mpsc:: UnboundedSender < M > ) ,
1609
1647
/// Use the provided function to enqueue the item.
@@ -1675,6 +1713,10 @@ impl<M: Message> Clone for UnboundedSender<M> {
1675
1713
}
1676
1714
1677
1715
impl < M : RemoteMessage > SerializedSender for UnboundedSender < M > {
1716
+ fn as_any ( & self ) -> & dyn Any {
1717
+ self
1718
+ }
1719
+
1678
1720
fn send_serialized ( & self , serialized : Serialized ) -> Result < bool , SerializedSenderError > {
1679
1721
match serialized. deserialized ( ) {
1680
1722
Ok ( message) => {
@@ -1757,6 +1799,10 @@ impl<M: Message> Clone for OnceSender<M> {
1757
1799
}
1758
1800
1759
1801
impl < M : RemoteMessage > SerializedSender for OnceSender < M > {
1802
+ fn as_any ( & self ) -> & dyn Any {
1803
+ self
1804
+ }
1805
+
1760
1806
fn send_serialized ( & self , serialized : Serialized ) -> Result < bool , SerializedSenderError > {
1761
1807
match serialized. deserialized ( ) {
1762
1808
Ok ( message) => self . send_once ( message) . map_err ( |e| SerializedSenderError {
@@ -1781,6 +1827,10 @@ struct UntypedUnboundedSender {
1781
1827
}
1782
1828
1783
1829
impl SerializedSender for UntypedUnboundedSender {
1830
+ fn as_any ( & self ) -> & dyn Any {
1831
+ self
1832
+ }
1833
+
1784
1834
fn send_serialized ( & self , serialized : Serialized ) -> Result < bool , SerializedSenderError > {
1785
1835
( self . sender ) ( serialized) . map_err ( |( data, err) | SerializedSenderError {
1786
1836
data,
0 commit comments