agent_tk/
module.rs

1//! This module contains the definition for an agent_tk module.
2
3use crate::delegation::{InputMessage, OutputMessage};
4
5/// Define an agent module. Each module can receive message as inputs and send via its outputs. All the messages are broadcasted. Each module has a single thread used for handling the messages. If longer computation are needed, they can spawn other modules.
6pub trait Module
7{
8  /// Type of the input message for this module
9  type InputMessage;
10  /// Type of the output message for this module
11  type OutputMessage;
12  /// Type of the private interface
13  type ModulePrivateInterface: ModulePrivateInterface<Self::InputMessage, Self::OutputMessage>;
14
15  /// This function is called ahead
16  fn prepare_interfaces(
17    cap: usize,
18  ) -> (
19    ModuleInterface<Self::InputMessage, Self::OutputMessage>,
20    Self::ModulePrivateInterface,
21  )
22  {
23    let (input_sender, mut input_receiver) = async_broadcast::broadcast::<Self::InputMessage>(cap);
24    let (output_sender, mut output_receiver) =
25      async_broadcast::broadcast::<Self::OutputMessage>(cap);
26
27    (
28      ModuleInterface::<Self::InputMessage, Self::OutputMessage>::new(
29        input_sender,
30        output_receiver.deactivate(),
31      ),
32      ModulePrivateInterface::new(input_receiver.deactivate(), output_sender),
33    )
34  }
35}
36
37/// Private interface for modules. Created outside of the module, but passed in constructor.
38pub trait ModulePrivateInterface<InputMessage, OutputMessage>
39{
40  /// Create a new private interface
41  fn new(
42    input_receiver: async_broadcast::InactiveReceiver<InputMessage>,
43    output_sender: async_broadcast::Sender<OutputMessage>,
44  ) -> Self;
45}
46
47/// Public module interface
48#[derive(Clone)]
49pub struct ModuleInterface<InputMessage, OutputMessage>
50{
51  input_sender: async_broadcast::Sender<InputMessage>,
52  output_receiver: async_broadcast::InactiveReceiver<OutputMessage>,
53}
54
55impl<InputMessage, OutputMessage> ModuleInterface<InputMessage, OutputMessage>
56{
57  fn new(
58    input_sender: async_broadcast::Sender<InputMessage>,
59    output_receiver: async_broadcast::InactiveReceiver<OutputMessage>,
60  ) -> Self
61  {
62    Self {
63      output_receiver,
64      input_sender,
65    }
66  }
67
68  pub(crate) fn output_receiver(&self) -> async_broadcast::Receiver<OutputMessage>
69  {
70    self.output_receiver.activate_cloned()
71  }
72  pub(crate) fn input_sender(&self) -> async_broadcast::Sender<InputMessage>
73  {
74    self.input_sender.clone()
75  }
76}
77
78macro_rules! create_module_private_interface {
79  ($name:ident, $input_message:ty, $output_message:ty) => {
80    #[allow(missing_docs)]
81    pub struct $name
82    {
83      input_receiver: async_broadcast::InactiveReceiver<$input_message>,
84      output_sender: async_broadcast::Sender<$output_message>,
85    }
86    impl $crate::module::ModulePrivateInterface<$input_message, $output_message> for $name
87    {
88      fn new(
89        input_receiver: async_broadcast::InactiveReceiver<$input_message>,
90        output_sender: async_broadcast::Sender<$output_message>,
91      ) -> Self
92      {
93        Self {
94          input_receiver,
95          output_sender,
96        }
97      }
98    }
99  };
100}
101
102pub(crate) use create_module_private_interface;