Skip to main content

elemental_object/
lib.rs

1pub mod context;
2pub mod facade;
3pub mod instant;
4pub mod pool;
5pub use facade::*;
6
7#[cfg(test)]
8mod testobj {
9    use std::time::Duration;
10    use tokio::{join, task::JoinSet, time::sleep};
11
12    use super::*;
13    #[tokio::test]
14    async fn test_fulfill() {
15        use std::sync::Arc;
16        use tokio::sync::Notify;
17        // FIXME: REMOVE nofity and we should resolve the wait problem by shutdown function, if the value is shutdown.
18        let ready = Arc::new(Notify::new());
19        let dropped = Arc::new(Notify::new());
20        let ready2 = ready.clone();
21        let dropped2 = dropped.clone();
22        let handle = tokio::spawn(async move {
23            println!("Fulfilling value");
24            provide_with_shutdown("value".to_string(), |value| async move {
25                println!("Shutting down value {}", value);
26            })
27            .await;
28            ready2.notify_one();
29            dropped2.notified().await;
30            println!("Fulfilling value again");
31            fulfill("value2".to_string()).await;
32            ready2.notify_one();
33        });
34        ready.notified().await;
35        println!("Got value here {:?}", acquire::<String>().await);
36        println!("Dropping value");
37        drop_value::<String>().await;
38        dropped.notify_one();
39        ready.notified().await;
40        println!("Acquired value again {:?}", acquire::<String>().await);
41        shutdown().await;
42        handle.await.unwrap();
43    }
44
45    #[tokio::test]
46    async fn test_provide() {
47        provide_with_shutdown("value".to_string(), |value| async move {
48            println!("Shutting down value {}", value);
49        })
50        .await;
51        provide_with_shutdown(1usize, |value| async move {
52            println!("Shutting down value {}", value);
53        })
54        .await;
55        println!("Got `String` value here {:?}", require::<String>().await);
56        println!("Got `usize` value here {:?}", require::<usize>().await);
57        println!("Dropping `String` value");
58        drop_value::<String>().await;
59    }
60
61    #[tokio::test]
62    async fn test_context() {
63        provide("Cheese".to_string()).await;
64        provide_with_shutdown(1usize, |value| async move {
65            println!(
66                "This means the context shutdown can also access the value, value = {}",
67                value
68            );
69        })
70        .await;
71        let context = ObjectContext::new();
72        let supplier = context.clone().run(async {
73            println!("Making delay in context");
74            sleep(Duration::from_secs(3)).await;
75            provide_context_with_shutdown("Hamburger".to_string(), |value| async move {
76                println!("Shutting down value {}", value);
77            })
78            .await;
79        });
80        let comsumer = context.clone().run(async {
81            let order = acquire::<String>().await;
82            println!("Got value in context {:?}", order);
83        });
84        join!(supplier, comsumer);
85        println!(
86            "After context shutdown, value is {:?}",
87            require::<String>().await
88        );
89        context.shutdown().await;
90        shutdown().await;
91    }
92    #[tokio::test]
93    async fn test_listener() {
94        use tokio::time::Instant;
95        let start = Instant::now();
96        let mut js = JoinSet::new();
97
98        js.spawn(async {
99            let bc = 1usize;
100            println!("Providing value {}", bc);
101            provide(bc).await;
102            sleep(Duration::from_secs(1)).await;
103            // hot reload value
104            let bc = 2usize;
105            println!("Providing value {}", bc);
106            provide(bc).await;
107            sleep(Duration::from_secs(2)).await;
108            drop_value::<usize>().await;
109        });
110        for index in 0..3usize {
111            js.spawn(async move {
112                while let Ok(value) = acquire::<usize>().await {
113                    // println!("#{} Got value {}", index, value);
114                    sleep(Duration::new(3, 0)).await;
115                    println!("Consumer #{} got value {}", index, value);
116                }
117                println!("#{} Exiting", index);
118            });
119        }
120        js.join_all().await;
121        shutdown().await;
122        let end = Instant::now();
123
124        println!("Total time taken: {:?}", end - start);
125    }
126}