async_maelstrom/process.rs
1//! Node process
2
3use async_std::channel::{bounded, Receiver, Sender};
4#[allow(unused)] // For doc
5use async_std::channel::{RecvError, SendError};
6use async_trait::async_trait;
7use serde::de::DeserializeOwned;
8use serde::Serialize;
9
10use crate::msg::{Msg, MsgId};
11#[allow(unused)] // For doc
12use crate::Error;
13use crate::{Id, Status};
14
15/// The process' interface to the Maelstrom network
16///
17/// Parameters
18/// - `W` the workload body type, e.g. [Echo](crate::msg::Echo)
19/// - `A` the application body type
20pub struct ProcNet<W, A>
21where
22 W: DeserializeOwned + Serialize,
23 A: DeserializeOwned + Serialize,
24{
25 /// Transmit queue
26 pub txq: Sender<Msg<W, A>>,
27 /// Receive queue
28 pub rxq: Receiver<Msg<W, A>>,
29}
30
31impl<W, A> Default for ProcNet<W, A>
32where
33 W: DeserializeOwned + Serialize,
34 A: DeserializeOwned + Serialize,
35{
36 fn default() -> Self {
37 let (txq, rxq) = bounded(1);
38 Self { txq, rxq }
39 }
40}
41
42/// Maelstrom [node process](https://github.com/jepsen-io/maelstrom/blob/main/doc/protocol.md#nodes-and-networks)
43///
44/// A process receives, processes and, if necessary, responds to
45/// - [Maelstrom workload messages](https://github.com/jepsen-io/maelstrom/blob/main/doc/workloads.md)
46/// - node-to-node messages according to the application's protocol that are delivered by the
47/// [crate::runtime::Runtime] via the process's [ProcNet] instance.
48///
49/// Parameters
50/// - `W` the workload body type, e.g. [Echo](crate::msg::Echo)
51/// - `A` the application body type
52#[async_trait]
53pub trait Process<W, A>
54where
55 W: DeserializeOwned + Serialize,
56 A: DeserializeOwned + Serialize,
57{
58 /// Create a process
59 ///
60 /// - `args` pass through command line args
61 /// - `net` a network interface to Maelstrom
62 /// - `id` this node's ID
63 /// - `ids` all protocol participants' IDs
64 /// - `start_msg_id` the first message ID to use. Initialization messages are handled by the
65 /// runtime, so this may be greater than 0.
66 fn init(
67 &mut self,
68 args: Vec<String>,
69 net: ProcNet<W, A>,
70 id: Id,
71 ids: Vec<Id>,
72 start_msg_id: MsgId,
73 );
74
75 /// Run the process
76 ///
77 /// The call should return when the process is complete or the runtime has shutdown.
78 ///
79 /// Return
80 /// - [Ok] IFF the process completed successfully,
81 /// - [Err]:[Error::Shutdown] IFF the runtime has shutdown,
82 /// - [Err] otherwise
83 async fn run(&self) -> Status;
84}