22
22
//! - [MessageSource]
23
23
//! declares that the actor under construction is a source of output messages,
24
24
//! and tells how to connect a [MessageSink] to which the messages will be directed.
25
- //! - [ServiceProvider]
26
- //! declares that the actor under construction is a service provider,
27
- //! that produces output messages as a reaction to input messages.
28
- //! - [ServiceConsumer]:
29
- //! declares that the actor under construction depends on a service provider,
30
- //! and tells how to connect such a [ServiceProvider] to interact with.
31
25
//! - [RuntimeRequestSink]:
32
26
//! defines how the runtime can connect the actor under construction.
33
27
//!
36
30
//! - An actor builder has to implement at least the [Builder] and [RuntimeRequestSink] traits,
37
31
//! so the runtime can connect itself to the actor and run it,
38
32
//! using its [spawn](crate::Runtime::spawn) method.
39
- //! - An actor builder that *depends* on some service provided by a [ServiceProvider],
40
- //! *must* implement the [ServiceConsumer] trait for the input, output and config types
41
- //! defined by the provider.
42
- //! - Similarly, if an actor needs to connect a [MessageSource],
33
+ //! - In order to define its input and output, an actor builder implements the [MessageSource] and [MessageSink] traits.
34
+ //! - If an actor needs to connect a [MessageSource],
43
35
//! its builder must implement the [MessageSink] trait with the appropriate message and config types.
44
36
//! - Vice versa, if an actor needs to send messages to some [MessageSink],
45
37
//! its builder must implement the [MessageSource] trait with the appropriate message and config types.
46
- //! - In order to define its input and output, an actor builder implements *either* the [ServiceProvider] trait
47
- //! or the [MessageSource] and [MessageSink] traits.
48
- //! - An actor builder implements the [MessageSource] and [MessageSink] traits
49
- //! when it makes sense for a peer to *only* send messages to or to *only* receive messages
50
- //! from the actor under construction.
51
- //! - An actor builder implements the [ServiceProvider] trait
52
- //! when there is a strong request-response relationship between the messages sent and received,
53
- //! the responses being meaningful only for the actor sending the triggering requests.
54
38
//!
55
39
//! An actor builder can use a [SimpleMessageBoxBuilder] to ease all these implementations.
56
40
//!
70
54
//! under construction needs to send messages to. This is the mirror of the previous responsibility:
71
55
//! each builder gives to the others clones of its senders and collects senders from others.
72
56
//! - This is why all the actor building traits
73
- //! ([MessageSource], [MessageSink], [ServiceProvider], [ServiceConsumer] and [RuntimeRequestSink])
57
+ //! ([MessageSource], [MessageSink] and [RuntimeRequestSink])
74
58
//! are related to exchanges of Sender. A sink gives to a source a sender attached to its receiver.
75
59
//! - To be precise, the actor builders exchange [DynSender] and not [Sender]. The difference is that
76
60
//! a [DynSender] can transform the messages sent by the source to adapt them to the sink expectations,
@@ -213,82 +197,6 @@ pub trait RuntimeRequestSink {
213
197
fn get_signal_sender ( & self ) -> DynSender < RuntimeRequest > ;
214
198
}
215
199
216
- /// A trait that defines that an actor provides a service
217
- /// by accepting `Request` messages and sending `Response` from/to its peers.
218
- ///
219
- /// In order to connect to a to `ServiceProvider<Req, Res, Conf>` and avail its services,
220
- /// the peer must be a `ServiceConsumer<Req, Res, Conf>`.
221
- ///
222
- /// The config parameter is typically used by the `ServiceConsumer`
223
- /// to register any message filtering criteria to the `ServiceProvider`.
224
- pub trait ServiceProvider < Request : Message , Response : Message , Config > {
225
- /// Connect a peer message box to the message box under construction
226
- fn add_peer ( & mut self , peer : & mut impl ServiceConsumer < Request , Response , Config > ) {
227
- let config = peer. get_config ( ) ;
228
- let response_sender = peer. get_response_sender ( ) ;
229
- let request_sender = self . connect_consumer ( config, response_sender) ;
230
- peer. set_request_sender ( request_sender) ;
231
- }
232
-
233
- /// Connect a consumer to the service provider under construction
234
- /// returning to that service consumer a sender for its requests.
235
- ///
236
- /// The consumer provides:
237
- /// - a config to filter the responses of interest,
238
- /// - a sender where the responses will have to be sent by the service.
239
- ///
240
- /// The consumer is given back:
241
- /// - a sender where its requests will have to be sent to the service.
242
- fn connect_consumer (
243
- & mut self ,
244
- config : Config ,
245
- response_sender : DynSender < Response > ,
246
- ) -> DynSender < Request > ;
247
- }
248
-
249
- /// A trait that defines that the actor under-construction
250
- /// is a consumer of the service provided by another actor that is a `ServiceProvider`.
251
- ///
252
- /// A `ServiceConsumer<Req, Res, Conf>` actor can be connected to another actor as its peer
253
- /// if that actor is a `ServiceProvider<Req, Res, Conf>`.
254
- pub trait ServiceConsumer < Request : Message , Response : Message , Config > {
255
- /// Return the config used by this actor to connect the service provider
256
- fn get_config ( & self ) -> Config ;
257
-
258
- /// Set the sender to be used by this actor's box to send requests
259
- fn set_request_sender ( & mut self , request_sender : DynSender < Request > ) ;
260
-
261
- /// Return a sender where the responses to this actor's box have to be sent
262
- fn get_response_sender ( & self ) -> DynSender < Response > ;
263
-
264
- /// Connect this client message box to the service message box
265
- fn set_connection (
266
- & mut self ,
267
- service : & mut impl ServiceProvider < Request , Response , Config > ,
268
- ) -> & mut Self
269
- where
270
- Self : Sized ,
271
- {
272
- service. add_peer ( self ) ;
273
- self
274
- }
275
-
276
- /// Connect this client message box to the service message box
277
- ///
278
- /// Return the updated client message box.
279
- #[ must_use]
280
- fn with_connection (
281
- mut self ,
282
- service : & mut impl ServiceProvider < Request , Response , Config > ,
283
- ) -> Self
284
- where
285
- Self : Sized ,
286
- {
287
- service. add_peer ( & mut self ) ;
288
- self
289
- }
290
- }
291
-
292
200
/// A [Builder] of [SimpleMessageBox]
293
201
///
294
202
/// This builder can be used as a building block for actor builders
@@ -353,42 +261,13 @@ pub trait ServiceConsumer<Request: Message, Response: Message, Config> {
353
261
/// }
354
262
/// ```
355
263
///
356
- /// Similarly, as a `SimpleMessageBoxBuilder` is a [ServiceProvider], this can be used
357
- /// to implement the [ServiceProvider] trait for an actor using a [SimpleMessageBox] for its main input.
358
- ///
359
- /// ```
360
- /// # use tedge_actors::{DynSender, NoConfig, ServiceConsumer, ServiceProvider, SimpleMessageBoxBuilder};
361
- /// # type MyActorConfig = i64;
362
- /// # type MyActorInput = i64;
363
- /// # type MyActorOutput = i64;
364
- /// struct MyActorBuilder {
365
- /// config: MyActorConfig,
366
- /// messages: SimpleMessageBoxBuilder<MyActorInput, MyActorOutput>,
367
- /// }
368
- ///
369
- /// impl ServiceProvider<MyActorInput, MyActorOutput, NoConfig> for MyActorBuilder {
370
- /// fn connect_consumer(
371
- /// &mut self,
372
- /// config: NoConfig,
373
- /// response_sender: DynSender<MyActorOutput>)
374
- /// -> DynSender<MyActorInput> {
375
- /// self.messages.connect_consumer(config, response_sender)
376
- /// }
377
- /// }
378
- /// ```
379
- ///
380
264
/// A notable use of [SimpleMessageBox] is for testing.
381
- /// As a `SimpleMessageBoxBuilder` is a [ServiceConsumer]
382
- /// one can use such a builder to connect and test an actor that is a [ServiceProvider].
383
- ///
384
- /// Similarly:
385
- /// - A `SimpleMessageBoxBuilder` is a [ServiceProvider] and can be used to test an actor that is a [ServiceConsumer].
386
265
/// - A `SimpleMessageBoxBuilder` is a [MessageSource] and can be used to test an actor that is a [MessageSink].
387
266
/// - A `SimpleMessageBoxBuilder` is a [MessageSink] and can be used to test an actor that is a [MessageSource].
388
267
///
389
268
/// ```
390
269
/// # use std::convert::Infallible;
391
- /// # use tedge_actors::{Actor, Builder, DynSender, MessageReceiver, NoConfig, RuntimeError, Sender, ServiceConsumer, ServiceProvider , SimpleMessageBox, SimpleMessageBoxBuilder};
270
+ /// # use tedge_actors::{Actor, Builder, DynSender, MessageReceiver, MessageSource, MessageSink, NoConfig, RuntimeError, Sender , SimpleMessageBox, SimpleMessageBoxBuilder};
392
271
/// # struct MyActorState (i64);
393
272
/// # type MyActorConfig = i64;
394
273
/// # type MyActorInput = i64;
@@ -412,9 +291,17 @@ pub trait ServiceConsumer<Request: Message, Response: Message, Config> {
412
291
/// # MyActorBuilder { config, messages }
413
292
/// # }
414
293
/// # }
415
- /// # impl ServiceProvider<MyActorInput, MyActorOutput, NoConfig> for MyActorBuilder {
416
- /// # fn connect_consumer(&mut self, config: NoConfig, response_sender: DynSender<MyActorOutput>) -> DynSender<MyActorInput> {
417
- /// # self.messages.connect_consumer(config, response_sender)
294
+ /// # impl MessageSource<MyActorOutput, NoConfig> for MyActorBuilder {
295
+ /// # fn register_peer(&mut self, config: NoConfig, sender: DynSender<MyActorOutput>) {
296
+ /// # self.messages.register_peer(config, sender)
297
+ /// # }
298
+ /// # }
299
+ /// # impl MessageSink<MyActorInput, NoConfig> for MyActorBuilder {
300
+ /// # fn get_config(&self) -> NoConfig {
301
+ /// # NoConfig
302
+ /// # }
303
+ /// # fn get_sender(&self) -> DynSender<MyActorInput> {
304
+ /// # self.messages.get_sender()
418
305
/// # }
419
306
/// # }
420
307
/// # impl Builder<MyActor> for MyActorBuilder {
@@ -448,7 +335,8 @@ pub trait ServiceConsumer<Request: Message, Response: Message, Config> {
448
335
/// // Connect a test box to an actor under test
449
336
/// let mut my_actor_builder = MyActorBuilder::new(MyActorConfig::default());
450
337
/// let mut test_box_builder = SimpleMessageBoxBuilder::new("Test box", 16);
451
- /// my_actor_builder.add_peer(&mut test_box_builder);
338
+ /// my_actor_builder.register_peer(NoConfig, test_box_builder.get_sender());
339
+ /// test_box_builder.register_peer(NoConfig, my_actor_builder.get_sender());
452
340
///
453
341
/// // Build the test box and run the actor
454
342
/// let mut test_box = test_box_builder.build();
@@ -489,38 +377,28 @@ impl<I: Message, O: Message> SimpleMessageBoxBuilder<I, O> {
489
377
input_receiver,
490
378
}
491
379
}
492
- }
493
380
494
- /// A `SimpleMessageBoxBuilder<Request,Response>` is a [ServiceProvider]
495
- /// accepting `Request` and sending back `Response`, with no specific config.
496
- impl < Req : Message , Res : Message , Config > ServiceProvider < Req , Res , Config >
497
- for SimpleMessageBoxBuilder < Req , Res >
498
- {
499
- fn connect_consumer (
381
+ /// Connect this client message box to the service message box
382
+ pub fn set_connection < Config > (
500
383
& mut self ,
501
- _config : Config ,
502
- response_sender : DynSender < Res > ,
503
- ) -> DynSender < Req > {
504
- self . output_sender = response_sender;
505
- self . input_sender . sender_clone ( )
506
- }
507
- }
508
-
509
- /// A `SimpleMessageBoxBuilder<Request,Response>` is a [ServiceConsumer]
510
- /// sending `Request` and expecting back `Response`, with no specific config.
511
- impl < Req : Message , Res : Message > ServiceConsumer < Req , Res , NoConfig >
512
- for SimpleMessageBoxBuilder < Res , Req >
513
- {
514
- fn get_config ( & self ) -> NoConfig {
515
- NoConfig
516
- }
517
-
518
- fn set_request_sender ( & mut self , request_sender : DynSender < Req > ) {
519
- self . output_sender = request_sender;
384
+ config : Config ,
385
+ service : & mut ( impl MessageSink < O , NoConfig > + MessageSource < I , Config > ) ,
386
+ ) {
387
+ service. register_peer ( config, self . input_sender . sender_clone ( ) ) ;
388
+ self . register_peer ( NoConfig , service. get_sender ( ) ) ;
520
389
}
521
390
522
- fn get_response_sender ( & self ) -> DynSender < Res > {
523
- self . input_sender . sender_clone ( )
391
+ /// Connect this client message box to the service message box
392
+ ///
393
+ /// Return the updated client message box.
394
+ #[ must_use]
395
+ pub fn with_connection < Config > (
396
+ mut self ,
397
+ config : Config ,
398
+ service : & mut ( impl MessageSink < O , NoConfig > + MessageSource < I , Config > ) ,
399
+ ) -> Self {
400
+ self . set_connection ( config, service) ;
401
+ self
524
402
}
525
403
}
526
404
0 commit comments