1use crate::LoadBalancer;
2use rand::seq::IteratorRandom;
3use std::future::Future;
4use std::sync::Arc;
5use std::time::Duration;
6use tokio::sync::RwLock;
7use tokio::task::JoinHandle;
8use tokio::{spawn, time::sleep};
9
10#[derive(Clone)]
12pub struct Entry<T>
13where
14 T: Send + Sync + Clone + 'static,
15{
16 pub value: T,
18}
19
20#[derive(Clone)]
22pub struct Random<T>
23where
24 T: Send + Sync + Clone + 'static,
25{
26 inner: Arc<RwLock<Vec<Entry<T>>>>,
28}
29
30impl<T> Random<T>
31where
32 T: Send + Sync + Clone + 'static,
33{
34 pub fn new(inner: Vec<T>) -> Self {
36 Self {
37 inner: Arc::new(RwLock::new(
38 inner.into_iter().map(|value| Entry { value }).collect(),
39 )),
40 }
41 }
42
43 pub async fn update<F, R, N>(&self, handler: F) -> anyhow::Result<N>
45 where
46 F: Fn(Arc<RwLock<Vec<Entry<T>>>>) -> R,
47 R: Future<Output = anyhow::Result<N>>,
48 {
49 handler(self.inner.clone()).await
50 }
51
52 pub async fn update_timer<F, R>(
54 &self,
55 handler: F,
56 interval: Duration,
57 ) -> anyhow::Result<JoinHandle<()>>
58 where
59 F: Fn(Arc<RwLock<Vec<Entry<T>>>>) -> R + Send + Sync + 'static,
60 R: Future<Output = anyhow::Result<()>> + Send,
61 {
62 handler(self.inner.clone()).await?;
63
64 let inner = self.inner.clone();
65
66 Ok(spawn(async move {
67 loop {
68 sleep(interval).await;
69 let _ = handler(inner.clone()).await;
70 }
71 }))
72 }
73}
74
75impl<T> LoadBalancer<T> for Random<T>
76where
77 T: Send + Sync + Clone + 'static,
78{
79 async fn alloc(&self) -> T {
81 self.inner
82 .read()
83 .await
84 .iter()
85 .choose(&mut rand::rng())
86 .map(|v| v.value.clone())
87 .unwrap()
88 }
89
90 fn try_alloc(&self) -> Option<T> {
92 self.inner
93 .try_read()
94 .ok()?
95 .iter()
96 .choose(&mut rand::rng())
97 .map(|v| v.value.clone())
98 }
99}