messaging_thread_pool/samples/randoms/
mod.rs

1use rand::{RngCore, SeedableRng};
2use rand_xoshiro::Xoshiro256Plus;
3use tracing::{Level, event};
4
5use crate::IdTargeted;
6use crate::ThreadShutdownResponse;
7use crate::pool_item;
8
9/// This represents a simple collection of random numbers which is hosted inside the thread pool
10///
11/// It is tied to a particular thread by the modulus of its id.
12///
13/// The interface that it supports is governed by its implementation of the PoolItem trait.
14/// This in turn needs to be supported by the use of two enums of supported requests and responses
15///
16/// It supports the following operations
17/// Init    creates a new Random with an stack based store of random numbers
18/// Mean    calculates the mean of the contained numbers
19/// Sum     calculates the sum of the contained numbers
20#[derive(Debug, PartialEq, Eq)]
21pub struct Randoms {
22    pub id: u64,
23    pub numbers: Vec<u64>,
24}
25
26impl IdTargeted for Randoms {
27    fn id(&self) -> u64 {
28        self.id
29    }
30}
31
32#[pool_item(Shutdown = "shutdown_pool_impl")]
33impl Randoms {
34    pub fn new(id: u64) -> Self {
35        let mut rng = Xoshiro256Plus::seed_from_u64(id);
36        let numbers = (0..10000).map(|_| rng.next_u64()).collect();
37        Self { id, numbers }
38    }
39
40    pub fn shutdown_pool_impl(&self) -> Vec<ThreadShutdownResponse> {
41        vec![ThreadShutdownResponse::new(self.id, vec![])]
42    }
43
44    #[messaging(MeanRequest, MeanResponse)]
45    pub fn mean(&self) -> u128 {
46        event!(Level::DEBUG, "evaluating mean");
47        self.numbers.iter().map(|n| *n as u128).sum::<u128>() / self.numbers.len() as u128
48    }
49
50    #[unsafe(no_mangle)]
51    #[messaging(SumRequest, SumResponse)]
52    pub fn sum(&self) -> u128 {
53        event!(Level::DEBUG, "evaluating sum");
54        // do this very slowly with unnecessary loops
55        for i in 0..=50 {
56            let r = self.numbers.iter().map(|n| *n as u128).sum::<u128>();
57            if i == 50 {
58                return r;
59            }
60        }
61        0
62    }
63
64    #[messaging(PanicRequest, PanicResponse)]
65    pub fn panic_call(&self) {
66        panic!("request to panic received")
67    }
68}
69
70pub use RandomsInit as RandomsAddRequest;
71
72impl MeanResponse {
73    pub fn mean(&self) -> u128 {
74        self.result
75    }
76}
77
78impl SumResponse {
79    pub fn sum(&self) -> u128 {
80        self.result
81    }
82}