evergreen/osrf/
sclient.rs

1//! Host Settings Module
2use crate::osrf::conf;
3use crate::Client;
4use crate::EgResult;
5use crate::EgValue;
6use std::sync::OnceLock;
7
8const SETTINGS_TIMEOUT: u64 = 10;
9
10/// If we fetch host settings, they will live here.
11/// They may be fetched and stored at most one time.
12static OSRF_HOST_CONFIG: OnceLock<HostSettings> = OnceLock::new();
13
14/// Read-only wrapper around a JSON blob of server setting values, which
15/// provides accessor methods for pulling setting values.
16pub struct HostSettings {
17    settings: EgValue,
18}
19
20impl HostSettings {
21    /// True if the host settings have been loaded.
22    pub fn is_loaded() -> bool {
23        OSRF_HOST_CONFIG.get().is_some()
24    }
25
26    /// Fetch the host config for our host and store the result in
27    /// our global host settings.
28    ///
29    pub fn load(client: &Client) -> EgResult<()> {
30        let mut ses = client.session("opensrf.settings");
31
32        let mut req = ses.request(
33            "opensrf.settings.host_config.get",
34            conf::config().hostname(),
35        )?;
36
37        if let Some(s) = req.recv_with_timeout(SETTINGS_TIMEOUT)? {
38            let sets = HostSettings { settings: s };
39            if OSRF_HOST_CONFIG.set(sets).is_err() {
40                return Err("Cannot apply host settings more than once".into());
41            }
42
43            Ok(())
44        } else {
45            Err("Settings server returned no response!".into())
46        }
47    }
48
49    /// Returns the full host settings config as a JsonValue.
50    pub fn settings(&self) -> &EgValue {
51        &self.settings
52    }
53
54    /// Returns the JsonValue at the specified path.
55    ///
56    /// Panics of the host config has not yet been retrieved.
57    ///
58    /// E.g. sclient.value("apps/opensrf.settings/unix_config/max_children");
59    pub fn get(slashpath: &str) -> EgResult<&EgValue> {
60        let hsets = OSRF_HOST_CONFIG
61            .get()
62            .ok_or_else(|| "Host settings have not been retrieved".to_string())?;
63
64        let mut value = hsets.settings();
65        for part in slashpath.split('/') {
66            value = &value[part]; // -> JsonValue::Null if key is not found.
67        }
68
69        Ok(value)
70    }
71}