From 9f25fbcf892195bc493a7eb468342219ff9b0844 Mon Sep 17 00:00:00 2001 From: Jan-Erik Rediger Date: Thu, 15 Dec 2022 13:43:08 +0100 Subject: [PATCH] Use a configuration builder to skip defaults on the configuration object --- glean-core/rlb/src/configuration.rs | 106 ++++++++++++++++++++++++++++ glean-core/rlb/src/lib.rs | 2 +- glean-core/rlb/tests/schema.rs | 31 +++----- 3 files changed, 115 insertions(+), 24 deletions(-) diff --git a/glean-core/rlb/src/configuration.rs b/glean-core/rlb/src/configuration.rs index 288f184a2b..75e5ecc813 100644 --- a/glean-core/rlb/src/configuration.rs +++ b/glean-core/rlb/src/configuration.rs @@ -35,3 +35,109 @@ pub struct Configuration { /// _before_ init, you shouldn't use this. pub trim_data_to_registered_pings: bool, } + +/// Configuration builder. +/// +/// Let's you build a configuration from the required fields +/// and let you set optional fields individually. +#[derive(Debug)] +pub struct Builder { + /// Required: Whether upload should be enabled. + pub upload_enabled: bool, + /// Required: Path to a directory to store all data in. + pub data_path: PathBuf, + /// Required: The application ID (will be sanitized during initialization). + pub application_id: String, + /// Optional: The maximum number of events to store before sending a ping containing events. + /// Default: `None` + pub max_events: Option, + /// Optional: Whether Glean should delay persistence of data from metrics with ping lifetime. + /// Default: `false` + pub delay_ping_lifetime_io: bool, + /// Optional: The server pings are sent to. + /// Default: `None` + pub server_endpoint: Option, + /// Optional: The instance of the uploader used to send pings. + /// Default: `None` + pub uploader: Option>, + /// Optional: Whether Glean should schedule "metrics" pings for you. + /// Default: `true` + pub use_core_mps: bool, + /// Optional: Whether Glean should limit its storage to only that of registered pings. + /// Unless you know that all your and your libraries' pings are appropriately registered + /// _before_ init, you shouldn't use this. + /// Default: `false` + pub trim_data_to_registered_pings: bool, +} + +impl Builder { + /// A new configuration builder. + pub fn new, S: Into>( + upload_enabled: bool, + data_path: P, + application_id: S, + ) -> Self { + Self { + upload_enabled, + data_path: data_path.into(), + application_id: application_id.into(), + max_events: None, + delay_ping_lifetime_io: false, + server_endpoint: None, + uploader: None, + use_core_mps: true, + trim_data_to_registered_pings: false, + } + } + + /// Generate the full configuration. + pub fn build(self) -> Configuration { + Configuration { + upload_enabled: self.upload_enabled, + data_path: self.data_path, + application_id: self.application_id, + max_events: self.max_events, + delay_ping_lifetime_io: self.delay_ping_lifetime_io, + server_endpoint: self.server_endpoint, + uploader: self.uploader, + use_core_mps: self.use_core_mps, + trim_data_to_registered_pings: self.trim_data_to_registered_pings, + } + } + + /// Set the maximum number of events to store before sending a ping containing events. + pub fn with_max_events(mut self, max_events: usize) -> Self { + self.max_events = Some(max_events); + self + } + + /// Set whether Glean should delay persistence of data from metrics with ping lifetime. + pub fn with_delay_ping_lifetime_io(mut self, value: bool) -> Self { + self.delay_ping_lifetime_io = value; + self + } + + /// Set the server pings are sent to. + pub fn with_server_endpoint>(mut self, server_endpoint: S) -> Self { + self.server_endpoint = Some(server_endpoint.into()); + self + } + + /// Set the instance of the uploader used to send pings. + pub fn with_uploader(mut self, uploader: U) -> Self { + self.uploader = Some(Box::new(uploader)); + self + } + + /// Set whether Glean should schedule "metrics" pings for you. + pub fn with_use_core_mps(mut self, value: bool) -> Self { + self.use_core_mps = value; + self + } + + /// Set whether Glean should limit its storage to only that of registered pings. + pub fn with_trim_data_to_registered_pings(mut self, value: bool) -> Self { + self.trim_data_to_registered_pings = value; + self + } +} diff --git a/glean-core/rlb/src/lib.rs b/glean-core/rlb/src/lib.rs index 17fe9097d4..8d8fa6634d 100644 --- a/glean-core/rlb/src/lib.rs +++ b/glean-core/rlb/src/lib.rs @@ -40,8 +40,8 @@ use std::collections::HashMap; use std::path::Path; -pub use configuration::Configuration; use configuration::DEFAULT_GLEAN_ENDPOINT; +pub use configuration::{Builder as ConfigurationBuilder, Configuration}; pub use core_metrics::ClientInfoMetrics; pub use glean_core::{ metrics::{Datetime, DistributionData, MemoryUnit, Rate, RecordedEvent, TimeUnit, TimerId}, diff --git a/glean-core/rlb/tests/schema.rs b/glean-core/rlb/tests/schema.rs index 8afbedf2d7..ecba431028 100644 --- a/glean-core/rlb/tests/schema.rs +++ b/glean-core/rlb/tests/schema.rs @@ -10,7 +10,7 @@ use serde_json::Value; //use glean::private::{DenominatorMetric, NumeratorMetric, RateMetric}; use glean::net::UploadResult; -use glean::{ClientInfoMetrics, Configuration}; +use glean::{ClientInfoMetrics, Configuration, ConfigurationBuilder}; const SCHEMA_JSON: &str = include_str!("../../../glean.1.schema.json"); @@ -28,17 +28,9 @@ fn new_glean(configuration: Option) -> tempfile::TempDir { let cfg = match configuration { Some(c) => c, - None => Configuration { - data_path: tmpname, - application_id: GLOBAL_APPLICATION_ID.into(), - upload_enabled: true, - max_events: None, - delay_ping_lifetime_io: false, - server_endpoint: Some("invalid-test-host".into()), - uploader: None, - use_core_mps: false, - trim_data_to_registered_pings: false, - }, + None => ConfigurationBuilder::new(true, tmpname, GLOBAL_APPLICATION_ID) + .with_server_endpoint("invalid-test-host") + .build(), }; let client_info = ClientInfoMetrics { @@ -80,17 +72,10 @@ fn validate_against_schema() { let dir = tempfile::tempdir().unwrap(); let tmpname = dir.path().to_path_buf(); - let cfg = Configuration { - data_path: tmpname, - application_id: GLOBAL_APPLICATION_ID.into(), - upload_enabled: true, - max_events: None, - delay_ping_lifetime_io: false, - server_endpoint: Some("invalid-test-host".into()), - uploader: Some(Box::new(ValidatingUploader { sender: s })), - use_core_mps: false, - trim_data_to_registered_pings: false, - }; + let cfg = ConfigurationBuilder::new(true, tmpname, GLOBAL_APPLICATION_ID) + .with_server_endpoint("invalid-test-host") + .with_uploader(ValidatingUploader { sender: s }) + .build(); let _ = new_glean(Some(cfg)); const PING_NAME: &str = "test-ping";