@@ -3,128 +3,118 @@ use crate::ChannelError;
3
3
use crate :: Message ;
4
4
use async_trait:: async_trait;
5
5
use futures:: channel:: mpsc;
6
+ use futures:: channel:: oneshot;
6
7
use futures:: SinkExt ;
7
8
8
9
/// A sender of messages of type `M`
9
10
///
10
- /// Actors don't access directly the `mpsc::Sender` of their peers,
11
+ /// Actors don't get direct access to the `mpsc::Sender` of their peers,
11
12
/// but use intermediate senders that adapt the messages when sent.
12
- pub type DynSender < M > = Box < dyn Sender < M > > ;
13
+ pub type DynSender < M > = Box < dyn CloneSender < M > > ;
13
14
14
15
#[ async_trait]
15
16
pub trait Sender < M > : ' static + Send + Sync {
16
17
/// Send a message to the receiver behind this sender,
17
18
/// returning an error if the receiver is no more expecting messages
18
19
async fn send ( & mut self , message : M ) -> Result < ( ) , ChannelError > ;
20
+ }
19
21
22
+ pub trait CloneSender < M > : Sender < M > {
20
23
/// Clone this sender in order to send messages to the same receiver from another actor
21
24
fn sender_clone ( & self ) -> DynSender < M > ;
22
25
23
- /// Closes this channel from the sender side, preventing any new messages.
24
- fn close_sender ( & mut self ) ;
26
+ /// Clone a cast of this sender into a `Box<dyn Sender<M>>`
27
+ ///
28
+ /// This is a workaround for https://github.com/rust-lang/rust/issues/65991
29
+ fn sender ( & self ) -> Box < dyn Sender < M > > ;
25
30
}
26
31
27
- impl < M : Message > Clone for DynSender < M > {
28
- fn clone ( & self ) -> Self {
29
- self . sender_clone ( )
32
+ impl < M , S : Clone + Sender < M > > CloneSender < M > for S {
33
+ fn sender_clone ( & self ) -> DynSender < M > {
34
+ Box :: new ( self . clone ( ) )
35
+ }
36
+
37
+ fn sender ( & self ) -> Box < dyn Sender < M > > {
38
+ Box :: new ( self . clone ( ) )
30
39
}
31
40
}
32
41
33
- /// An `mpsc::Sender<M>` is a `DynSender<N>` provided `N` implements `Into<M>`
34
- impl < M : Message , N : Message + Into < M > > From < mpsc:: Sender < M > > for DynSender < N > {
35
- fn from ( sender : mpsc:: Sender < M > ) -> Self {
42
+ impl < M , S : Clone + Sender < M > > From < S > for DynSender < M > {
43
+ fn from ( sender : S ) -> Self {
36
44
Box :: new ( sender)
37
45
}
38
46
}
39
47
48
+ /// A `DynSender<M>` is a `DynSender<N>` provided `N` implements `Into<M>`
40
49
#[ async_trait]
41
- impl < M : Message , N : Message + Into < M > > Sender < N > for mpsc :: Sender < M > {
50
+ impl < M : Message , N : Message + Into < M > > Sender < N > for DynSender < M > {
42
51
async fn send ( & mut self , message : N ) -> Result < ( ) , ChannelError > {
43
- Ok ( SinkExt :: send ( & mut self , message. into ( ) ) . await ?)
52
+ Ok ( self . as_mut ( ) . send ( message. into ( ) ) . await ?)
53
+ }
54
+ }
55
+
56
+ #[ async_trait]
57
+ impl < M : Message , N : Message + Into < M > > Sender < N > for Box < dyn Sender < M > > {
58
+ async fn send ( & mut self , message : N ) -> Result < ( ) , ChannelError > {
59
+ Ok ( self . as_mut ( ) . send ( message. into ( ) ) . await ?)
44
60
}
61
+ }
45
62
63
+ #[ async_trait]
64
+ impl < M : Message , N : Message + Into < M > > CloneSender < N > for DynSender < M > {
46
65
fn sender_clone ( & self ) -> DynSender < N > {
47
- Box :: new ( self . clone ( ) )
66
+ Box :: new ( self . as_ref ( ) . sender_clone ( ) )
48
67
}
49
68
50
- fn close_sender ( & mut self ) {
51
- self . close_channel ( ) ;
69
+ fn sender ( & self ) -> Box < dyn Sender < N > > {
70
+ Box :: new ( self . as_ref ( ) . sender ( ) )
52
71
}
53
72
}
54
73
55
- /// An `mpsc::UnboundedSender<M>` is a `DynSender<N>` provided `N` implements `Into<M>`
56
- impl < M : Message , N : Message + Into < M > > From < mpsc:: UnboundedSender < M > > for DynSender < N > {
57
- fn from ( sender : mpsc:: UnboundedSender < M > ) -> Self {
58
- Box :: new ( sender)
74
+ /// An `mpsc::Sender<M>` is a `DynSender<M>`
75
+ #[ async_trait]
76
+ impl < M : Message , N : Message + Into < M > > Sender < N > for mpsc:: Sender < M > {
77
+ async fn send ( & mut self , message : N ) -> Result < ( ) , ChannelError > {
78
+ Ok ( SinkExt :: send ( & mut self , message. into ( ) ) . await ?)
59
79
}
60
80
}
61
81
82
+ /// An `mpsc::UnboundedSender<M>` is a `DynSender<N>` provided `N` implements `Into<M>`
62
83
#[ async_trait]
63
84
impl < M : Message , N : Message + Into < M > > Sender < N > for mpsc:: UnboundedSender < M > {
64
85
async fn send ( & mut self , message : N ) -> Result < ( ) , ChannelError > {
65
86
Ok ( SinkExt :: send ( & mut self , message. into ( ) ) . await ?)
66
87
}
67
-
68
- fn sender_clone ( & self ) -> DynSender < N > {
69
- Box :: new ( self . clone ( ) )
70
- }
71
-
72
- fn close_sender ( & mut self ) {
73
- self . close_channel ( ) ;
74
- }
75
88
}
76
89
77
- /// Make a `DynSender<N>` from a `DynSender<M>`
78
- ///
79
- /// This is a workaround to the fact the compiler rejects a From implementation:
90
+ /// A `oneshot::Sender<M>` is a `Sender<N>` provided `N` implements `Into<M>`
80
91
///
81
- /// ```shell
92
+ /// There is one caveat. The `oneshot::Sender::send()` method consumes the sender,
93
+ /// hence the one shot sender is wrapped inside an `Option`.
82
94
///
83
- /// impl<M: Message, N: Message + Into<M>> From<DynSender<M>> for DynSender<N> {
84
- /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
85
- /// |
86
- /// = note: conflicting implementation in crate `core`:
87
- /// - impl<T> From<T> for T;
88
- /// ```
89
- pub fn adapt < M : Message , N : Message + Into < M > > ( sender : & DynSender < M > ) -> DynSender < N > {
90
- Box :: new ( sender. clone ( ) )
91
- }
92
-
95
+ /// Such a [Sender] can only be used once:
96
+ /// - it cannot be cloned
97
+ /// - any message sent after a first one will be silently ignored
98
+ /// - a message sent while the receiver has been drop will also be silently ignored
93
99
#[ async_trait]
94
- impl < M : Message , N : Message + Into < M > > Sender < N > for DynSender < M > {
100
+ impl < M : Message , N : Message + Into < M > > Sender < N > for Option < oneshot :: Sender < M > > {
95
101
async fn send ( & mut self , message : N ) -> Result < ( ) , ChannelError > {
96
- Ok ( self . as_mut ( ) . send ( message. into ( ) ) . await ?)
97
- }
98
-
99
- fn sender_clone ( & self ) -> DynSender < N > {
100
- Box :: new ( self . as_ref ( ) . sender_clone ( ) )
101
- }
102
-
103
- fn close_sender ( & mut self ) {
104
- self . as_mut ( ) . close_sender ( )
102
+ if let Some ( sender) = self . take ( ) {
103
+ let _ = sender. send ( message. into ( ) ) ;
104
+ }
105
+ Ok ( ( ) )
105
106
}
106
107
}
107
108
108
109
/// A sender that discards messages instead of sending them
110
+ #[ derive( Clone ) ]
109
111
pub struct NullSender ;
110
112
111
113
#[ async_trait]
112
114
impl < M : Message > Sender < M > for NullSender {
113
115
async fn send ( & mut self , _message : M ) -> Result < ( ) , ChannelError > {
114
116
Ok ( ( ) )
115
117
}
116
-
117
- fn sender_clone ( & self ) -> DynSender < M > {
118
- Box :: new ( NullSender )
119
- }
120
-
121
- fn close_sender ( & mut self ) { }
122
- }
123
-
124
- impl < M : Message > From < NullSender > for DynSender < M > {
125
- fn from ( sender : NullSender ) -> Self {
126
- Box :: new ( sender)
127
- }
128
118
}
129
119
130
120
/// A sender that transforms the messages on the fly
@@ -133,6 +123,15 @@ pub struct MappingSender<F, M> {
133
123
cast : std:: sync:: Arc < F > ,
134
124
}
135
125
126
+ impl < F , M : ' static > Clone for MappingSender < F , M > {
127
+ fn clone ( & self ) -> Self {
128
+ MappingSender {
129
+ inner : self . inner . sender_clone ( ) ,
130
+ cast : self . cast . clone ( ) ,
131
+ }
132
+ }
133
+ }
134
+
136
135
impl < F , M > MappingSender < F , M > {
137
136
pub fn new ( inner : DynSender < M > , cast : F ) -> Self {
138
137
MappingSender {
@@ -157,30 +156,6 @@ where
157
156
}
158
157
Ok ( ( ) )
159
158
}
160
-
161
- fn sender_clone ( & self ) -> DynSender < M > {
162
- Box :: new ( MappingSender {
163
- inner : self . inner . sender_clone ( ) ,
164
- cast : self . cast . clone ( ) ,
165
- } )
166
- }
167
-
168
- fn close_sender ( & mut self ) {
169
- self . inner . as_mut ( ) . close_sender ( )
170
- }
171
- }
172
-
173
- impl < M , N , NS , F > From < MappingSender < F , N > > for DynSender < M >
174
- where
175
- M : Message ,
176
- N : Message ,
177
- NS : Iterator < Item = N > + Send ,
178
- F : Fn ( M ) -> NS ,
179
- F : ' static + Sync + Send ,
180
- {
181
- fn from ( value : MappingSender < F , N > ) -> Self {
182
- Box :: new ( value)
183
- }
184
159
}
185
160
186
161
#[ cfg( test) ]
@@ -233,8 +208,8 @@ mod tests {
233
208
impl From < DynSender < Msg > > for Peers {
234
209
fn from ( recipient : DynSender < Msg > ) -> Self {
235
210
Peers {
236
- peer_1 : adapt ( & recipient) ,
237
- peer_2 : adapt ( & recipient) ,
211
+ peer_1 : recipient. sender_clone ( ) ,
212
+ peer_2 : recipient. sender_clone ( ) ,
238
213
}
239
214
}
240
215
}
0 commit comments