basic/
basic.rs

1extern crate syncpool;
2
3use std::collections::HashMap;
4use std::mem::MaybeUninit;
5use std::pin::Pin;
6use std::sync::mpsc;
7use std::sync::mpsc::SyncSender;
8use std::thread;
9use std::time::Duration;
10use syncpool::prelude::*;
11
12/// Number of producers that runs in this test
13const COUNT: usize = 128;
14
15/// A shared pool, one can imagine other ways of sharing the pool concurrently, here we choose to use
16/// an unsafe version to simplify the example.
17static mut POOL: MaybeUninit<SyncPool<ComplexStruct>> = MaybeUninit::uninit();
18
19#[derive(Default, Debug)]
20struct ComplexStruct {
21    id: usize,
22    name: String,
23    body: Vec<String>,
24    flags: Vec<usize>,
25    children: Vec<usize>,
26    index: HashMap<usize, String>,
27    rev_index: HashMap<String, usize>,
28}
29
30/// Make sure we build up the pool before use
31unsafe fn pool_setup() -> (
32    Pin<&'static mut SyncPool<ComplexStruct>>,
33    Pin<&'static mut SyncPool<ComplexStruct>>,
34) {
35    POOL.as_mut_ptr().write(SyncPool::with_size(COUNT / 2));
36
37    (
38        Pin::new(&mut *POOL.as_mut_ptr()),
39        Pin::new(&mut *POOL.as_mut_ptr()),
40    )
41}
42
43/// Main example body
44fn main() {
45    // let's make the pool slightly smaller than the demand, this will simulate a service under pressure
46    // such that the pool can't completely meet the demand without dynamically expand the pool.
47    let (pinned_producer, pinned_consumer) = unsafe { pool_setup() };
48
49    // make the channel that establish a concurrent pipeline.
50    let (tx, rx) = mpsc::sync_channel(64);
51
52    // data producer loop
53    thread::spawn(move || {
54        let producer = pinned_producer.get_mut();
55
56        for i in 0..COUNT {
57            run(producer, &tx, i);
58        }
59    });
60
61    // data consumer logic
62    let handler = thread::spawn(move || {
63        let consumer = pinned_consumer.get_mut();
64
65        for content in rx {
66            println!("Receiving struct with id: {}", content.id);
67            consumer.put(content);
68        }
69    });
70
71    // wait for the receiver to finish and print the result.
72    handler.join().unwrap_or_default();
73
74    println!("All done...");
75}
76
77fn run(pool: &mut SyncPool<ComplexStruct>, chan: &SyncSender<Box<ComplexStruct>>, id: usize) {
78    // take a pre-init struct from the pool
79    let mut content = pool.get();
80    content.id = id;
81
82    // assuming we're doing some stuff in this period
83    thread::sleep(Duration::from_nanos(32));
84
85    // done with the stuff, send the result out.
86    chan.send(content).unwrap_or_default();
87}