viewstamped_replication/
client.rs

1use crate::configuration::Configuration;
2use crate::request::{ClientIdentifier, Reply, Request, RequestIdentifier};
3use crate::viewstamp::View;
4
5pub struct Client {
6    configuration: Configuration,
7    view: View,
8    identifier: ClientIdentifier,
9    last_request: RequestIdentifier,
10}
11
12impl Client {
13    pub fn new(configuration: Configuration) -> Self {
14        Self {
15            configuration,
16            view: Default::default(),
17            identifier: Default::default(),
18            last_request: Default::default(),
19        }
20    }
21
22    pub fn identifier(&self) -> ClientIdentifier {
23        self.identifier
24    }
25
26    pub fn update_view<P>(&mut self, reply: &Reply<P>) {
27        self.view = self.view.max(reply.view);
28    }
29
30    pub fn new_request<P>(&mut self, payload: P) -> Request<P> {
31        self.last_request.increment();
32
33        Request {
34            payload,
35            client: self.identifier,
36            id: self.last_request,
37        }
38    }
39
40    pub fn primary(&self) -> usize {
41        self.configuration % self.view
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48    use std::cmp::Ordering;
49
50    #[test]
51    fn requests() {
52        let configuration = Configuration::from(5);
53        let mut client = Client::new(configuration);
54
55        let request_a = client.new_request(5);
56        let request_b = client.new_request(5);
57
58        assert_ne!(request_a.id, request_b.id);
59        assert_eq!(request_a.id.cmp(&request_b.id), Ordering::Less);
60    }
61}