statsig_rust/
global_configs.rs1use crate::{log_e, DynamicValue};
2use lazy_static::lazy_static;
3use std::{
4 collections::HashMap,
5 sync::{Arc, RwLock, Weak},
6};
7
8const TAG: &str = stringify!(GlobalConfigs);
9
10pub const MAX_SAMPLING_RATE: f64 = 10000.0;
11
12lazy_static! {
13 static ref GLOBAL_CONFIG_INSTANCES: RwLock<HashMap<String, Weak<GlobalConfigs>>> =
14 RwLock::new(HashMap::new());
15}
16
17struct Configs {
18 sdk_configs: HashMap<String, DynamicValue>,
19 diagnostics_sampling_rates: HashMap<String, f64>,
20}
21
22pub struct GlobalConfigs {
23 configs: RwLock<Configs>,
24}
25
26impl GlobalConfigs {
27 pub fn get_instance(sdk_key: &str) -> Arc<GlobalConfigs> {
28 match GLOBAL_CONFIG_INSTANCES.read() {
29 Ok(read_guard) => {
30 if let Some(instance) = read_guard.get(sdk_key) {
31 if let Some(instance) = instance.upgrade() {
32 return instance.clone();
33 }
34 }
35 }
36 Err(e) => {
37 log_e!(TAG, "Failed to get read guard: {}", e);
38 }
39 }
40
41 let instance = Arc::new(GlobalConfigs {
42 configs: RwLock::new(Configs {
43 sdk_configs: HashMap::new(),
44 diagnostics_sampling_rates: HashMap::from([
45 ("initialize".to_string(), 10000.0),
46 ("config_sync".to_string(), 1000.0),
47 ("dcs".to_string(), 1000.0),
48 ("get_id_list".to_string(), 100.0), ]),
50 }),
51 });
52
53 match GLOBAL_CONFIG_INSTANCES.write() {
54 Ok(mut write_guard) => {
55 write_guard.insert(sdk_key.into(), Arc::downgrade(&instance));
56 }
57 Err(e) => {
58 log_e!(TAG, "Failed to get write guard: {}", e);
59 }
60 }
61
62 instance
63 }
64
65 pub fn set_sdk_configs(&self, new_configs: HashMap<String, DynamicValue>) {
66 match self.configs.write() {
67 Ok(mut configs_guard) => {
68 for (key, value) in new_configs {
69 configs_guard.sdk_configs.insert(key, value);
70 }
71 }
72 Err(e) => {
73 log_e!(TAG, "Failed to get write guard: {}", e);
74 }
75 }
76 }
77
78 pub fn set_diagnostics_sampling_rates(&self, new_sampling_rate: HashMap<String, f64>) {
79 match self.configs.write() {
80 Ok(mut configs_guard) => {
81 for (key, rate) in new_sampling_rate {
82 let clamped_rate = rate.clamp(0.0, MAX_SAMPLING_RATE);
83 configs_guard
84 .diagnostics_sampling_rates
85 .insert(key, clamped_rate);
86 }
87 }
88 Err(e) => {
89 log_e!(TAG, "Failed to get write guard: {}", e);
90 }
91 }
92 }
93
94 pub fn use_sdk_config_value<T>(
95 &self,
96 key: &str,
97 f: impl FnOnce(Option<&DynamicValue>) -> T,
98 ) -> T {
99 match self.configs.read() {
100 Ok(configs_guard) => f(configs_guard.sdk_configs.get(key)),
101 Err(e) => {
102 log_e!(TAG, "Failed to get read guard: {}", e);
103 f(None)
104 }
105 }
106 }
107
108 pub fn use_diagnostics_sampling_rate<T>(
109 &self,
110 key: &str,
111 f: impl FnOnce(Option<&f64>) -> T,
112 ) -> T {
113 match self.configs.read() {
114 Ok(configs_guard) => f(configs_guard.diagnostics_sampling_rates.get(key)),
115 Err(e) => {
116 log_e!(TAG, "Failed to get read guard: {}", e);
117 f(None)
118 }
119 }
120 }
121}