orlando_cluster/
placement.rs1use crate::hash_ring::{HashRing, SiloAddress};
2
3pub trait PlacementStrategy: Send + Sync + 'static {
5 fn place(
8 &self,
9 grain_type: &str,
10 grain_key: &str,
11 local_silo_id: &str,
12 ring: &HashRing,
13 ) -> Option<SiloAddress>;
14}
15
16#[derive(Debug)]
19pub struct HashBasedPlacement;
20
21impl PlacementStrategy for HashBasedPlacement {
22 fn place(
23 &self,
24 grain_type: &str,
25 grain_key: &str,
26 _local_silo_id: &str,
27 ring: &HashRing,
28 ) -> Option<SiloAddress> {
29 let ring_key = format!("{}/{}", grain_type, grain_key);
30 ring.get(&ring_key).cloned()
31 }
32}
33
34#[derive(Debug)]
37pub struct PreferLocalPlacement;
38
39impl PlacementStrategy for PreferLocalPlacement {
40 fn place(
41 &self,
42 _grain_type: &str,
43 _grain_key: &str,
44 local_silo_id: &str,
45 ring: &HashRing,
46 ) -> Option<SiloAddress> {
47 ring.members()
48 .into_iter()
49 .find(|s| s.silo_id == local_silo_id)
50 }
51}
52
53#[derive(Debug)]
57pub struct RandomPlacement;
58
59impl PlacementStrategy for RandomPlacement {
60 fn place(
61 &self,
62 _grain_type: &str,
63 _grain_key: &str,
64 _local_silo_id: &str,
65 ring: &HashRing,
66 ) -> Option<SiloAddress> {
67 let members = ring.members();
68 if members.is_empty() {
69 return None;
70 }
71 let idx = fastrand::usize(..members.len());
72 Some(members[idx].clone())
73 }
74}