Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions components/nimbus/src/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use std::collections::HashMap;

use serde_json::{Map, Value};

use crate::error::Result;

/// Simple trait to allow merging of similar objects.
Expand Down Expand Up @@ -34,7 +38,6 @@ impl<T: Defaults + Clone> Defaults for Option<T> {
}
}

use serde_json::{Map, Value};
/// We implement https://datatracker.ietf.org/doc/html/rfc7396
/// such that self is patching the fallback.
/// The result is the patched object.
Expand Down Expand Up @@ -76,7 +79,6 @@ impl Defaults for Map<String, Value> {
}
}

use std::collections::HashMap;
/// Merge the two `HashMap`s, with self acting as the dominant
/// of the two.
///
Expand Down
27 changes: 14 additions & 13 deletions components/nimbus/src/enrollment.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::collections::{HashMap, HashSet};
use std::fmt::{self, Display};
use std::time::{Duration, SystemTime, UNIX_EPOCH};

use serde_derive::{Deserialize, Serialize};

use crate::defaults::Defaults;
use crate::error::{NimbusError, Result, debug, warn};
use crate::evaluator::evaluate_enrollment;
use crate::json;
#[cfg(feature = "stateful")]
use crate::stateful::gecko_prefs::{GeckoPrefStore, OriginalGeckoPref, PrefUnenrollReason};
use crate::{
AvailableRandomizationUnits, Experiment, FeatureConfig, NimbusTargetingHelper,
SLUG_REPLACEMENT_PATTERN,
defaults::Defaults,
error::{NimbusError, Result, debug, warn},
evaluator::evaluate_enrollment,
json,
};
use serde_derive::*;
use std::{
collections::{HashMap, HashSet},
fmt::{Display, Formatter, Result as FmtResult},
time::{Duration, SystemTime, UNIX_EPOCH},
};

pub(crate) const PREVIOUS_ENROLLMENTS_GC_TIME: Duration = Duration::from_secs(365 * 24 * 3600);
Expand All @@ -32,7 +33,7 @@ pub enum EnrolledReason {
}

impl Display for EnrolledReason {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(
match self {
EnrolledReason::Qualified => "Qualified",
Expand Down Expand Up @@ -66,7 +67,7 @@ pub enum NotEnrolledReason {
}

impl Display for NotEnrolledReason {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(
match self {
NotEnrolledReason::DifferentAppName => "DifferentAppName",
Expand Down Expand Up @@ -117,7 +118,7 @@ pub enum DisqualifiedReason {
}

impl Display for DisqualifiedReason {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(
match self {
DisqualifiedReason::Error => "Error",
Expand Down
4 changes: 2 additions & 2 deletions components/nimbus/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
//! TODO: Implement proper error handling, this would include defining the error enum,
//! impl std::error::Error using `thiserror` and ensuring all errors are handled appropriately

use std::num::{ParseIntError, TryFromIntError};

// reexport logging helpers.
pub use error_support::{debug, error, info, trace, warn};

#[cfg(feature = "stateful")]
use firefox_versioning::error::VersionParsingError;
use std::num::{ParseIntError, TryFromIntError};

#[derive(Debug, thiserror::Error)]
pub enum NimbusError {
Expand Down
23 changes: 10 additions & 13 deletions components/nimbus/src/evaluator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

use crate::{
AvailableRandomizationUnits, Branch, Experiment, NimbusTargetingHelper,
enrollment::{EnrolledReason, EnrollmentStatus, ExperimentEnrollment, NotEnrolledReason},
error::{NimbusError, Result, debug, info},
sampling,
};
use serde_derive::*;
use serde_json::Value;

cfg_if::cfg_if! {
if #[cfg(feature = "stateful")] {
pub use crate::stateful::evaluator::*;
} else {
pub use crate::stateless::evaluator::*;
}
}
use crate::enrollment::{
EnrolledReason, EnrollmentStatus, ExperimentEnrollment, NotEnrolledReason,
};
use crate::error::{NimbusError, Result, debug, info};
use crate::sampling;
#[cfg(feature = "stateful")]
pub use crate::stateful::evaluator::*;
#[cfg(not(feature = "stateful"))]
pub use crate::stateless::evaluator::*;
use crate::{AvailableRandomizationUnits, Branch, Experiment, NimbusTargetingHelper};

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Bucket {}
Expand Down
1 change: 1 addition & 0 deletions components/nimbus/src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use serde_json::{Map, Value};

use std::collections::HashMap;

#[cfg(feature = "stateful")]
Expand Down
21 changes: 10 additions & 11 deletions components/nimbus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

extern crate core;

mod defaults;
mod enrollment;
mod evaluator;
Expand All @@ -16,26 +14,27 @@ pub mod error;
pub mod metrics;
pub mod schema;

pub use enrollment::{EnrolledFeature, EnrollmentStatus};
pub use error::{NimbusError, Result};
pub use crate::enrollment::{EnrolledFeature, EnrollmentStatus};
pub use crate::error::{NimbusError, Result};
#[cfg(debug_assertions)]
pub use evaluator::evaluate_enrollment;
pub use schema::*;
pub use targeting::NimbusTargetingHelper;
pub use crate::evaluator::evaluate_enrollment;
pub use crate::schema::*;
pub use crate::targeting::NimbusTargetingHelper;

cfg_if::cfg_if! {
if #[cfg(feature = "stateful")] {

pub mod stateful;

pub use stateful::nimbus_client::*;
pub use stateful::matcher::AppContext;
pub use remote_settings::{RemoteSettingsConfig, RemoteSettingsServer};

pub use crate::stateful::nimbus_client::*;
pub use crate::stateful::matcher::AppContext;
} else {
pub mod stateless;

pub use stateless::cirrus_client::*;
pub use stateless::matcher::AppContext;
pub use crate::stateless::cirrus_client::*;
pub use crate::stateless::matcher::AppContext;
}
}

Expand Down
8 changes: 5 additions & 3 deletions components/nimbus/src/metrics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use serde_derive::{Deserialize, Serialize};

use crate::enrollment::ExperimentEnrollment;
use crate::{EnrolledFeature, EnrollmentStatus};

#[cfg(feature = "stateful")]
use crate::enrollment::PreviousGeckoPrefState;

use crate::{EnrolledFeature, EnrollmentStatus, enrollment::ExperimentEnrollment};
use serde_derive::{Deserialize, Serialize};

pub trait MetricsHandler: Send + Sync {
#[cfg(feature = "stateful")]
fn record_enrollment_statuses(&self, enrollment_status_extras: Vec<EnrollmentStatusExtraDef>);
Expand Down
3 changes: 2 additions & 1 deletion components/nimbus/src/sampling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
//! This module implements the sampling logic required to hash,
//! randomize and pick branches using pre-set ratios.

use crate::error::{NimbusError, Result};
use sha2::{Digest, Sha256};

use crate::error::{NimbusError, Result};

const HASH_BITS: u32 = 48;
const HASH_LENGTH: u32 = HASH_BITS / 4;

Expand Down
12 changes: 8 additions & 4 deletions components/nimbus/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use crate::error::{trace, warn};
use crate::{NimbusError, Result, defaults::Defaults, enrollment::ExperimentMetadata};
use serde_derive::*;
use serde_json::{Map, Value};
use std::collections::HashSet;

use serde_derive::{Deserialize, Serialize};
use serde_json::{Map, Value};
use uuid::Uuid;

use crate::defaults::Defaults;
use crate::enrollment::ExperimentMetadata;
use crate::error::{trace, warn};
use crate::{NimbusError, Result};

const DEFAULT_TOTAL_BUCKETS: u32 = 10000;

#[derive(Debug, Clone)]
Expand Down
14 changes: 7 additions & 7 deletions components/nimbus/src/stateful/behavior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::{
error::{BehaviorError, NimbusError, Result},
stateful::persistence::{Database, StoreId},
};
use chrono::{DateTime, Datelike, Duration, TimeZone, Utc};
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
use std::collections::vec_deque::Iter;
use std::collections::{HashMap, VecDeque};
use std::fmt;
use std::hash::{Hash, Hasher};
use std::str::FromStr;
use std::sync::{Arc, Mutex};

use chrono::{DateTime, Datelike, Duration, TimeZone, Utc};
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};

use crate::error::{BehaviorError, NimbusError, Result};
use crate::stateful::persistence::{Database, StoreId};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub enum Interval {
Minutes,
Expand Down
7 changes: 4 additions & 3 deletions components/nimbus/src/stateful/client/fs_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
//! (eg, for testing against experiments which are not deployed anywhere) and
//! for tests.

use crate::Experiment;
use crate::error::{Result, info, warn};
use crate::stateful::client::SettingsClient;
use std::ffi::OsStr;
use std::fs::File;
use std::io::BufReader;
use std::path::{Path, PathBuf};

use crate::Experiment;
use crate::error::{Result, info, warn};
use crate::stateful::client::SettingsClient;

pub struct FileSystemClient {
path: PathBuf,
}
Expand Down
5 changes: 3 additions & 2 deletions components/nimbus/src/stateful/client/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
use std::sync::Arc;

use remote_settings::{RemoteSettingsClient, RemoteSettingsError};
use serde_json::json;

use crate::NimbusError;
use crate::error::Result;
use crate::schema::parse_experiments;
use crate::stateful::client::{Experiment, SettingsClient};
use remote_settings::{RemoteSettingsClient, RemoteSettingsError};
use serde_json::json;

impl SettingsClient for Arc<RemoteSettingsClient> {
fn get_experiments_metadata(&self) -> Result<String> {
Expand Down
10 changes: 6 additions & 4 deletions components/nimbus/src/stateful/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
mod fs_client;
pub(crate) mod http_client;
pub(crate) mod null_client;

use std::sync::Arc;

use crate::Experiment;
use crate::error::{NimbusError, Result};
use fs_client::FileSystemClient;
use null_client::NullClient;
use remote_settings::RemoteSettingsService;
use url::Url;

use crate::Experiment;
use crate::error::{NimbusError, Result};
use crate::stateful::client::fs_client::FileSystemClient;
use crate::stateful::client::null_client::NullClient;

pub struct NimbusServerSettings {
pub rs_service: Arc<RemoteSettingsService>,
pub collection_name: String,
Expand Down
21 changes: 9 additions & 12 deletions components/nimbus/src/stateful/dbcache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,18 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::{
EnrolledExperiment, Experiment,
enrollment::{
EnrolledFeature, EnrolledFeatureConfig, ExperimentEnrollment, map_features_by_feature_id,
},
error::{NimbusError, Result, warn},
stateful::{
enrollment::get_enrollments,
gecko_prefs::GeckoPrefStore,
persistence::{Database, StoreId, Writer},
},
};
use std::collections::{HashMap, HashSet};
use std::sync::{Arc, RwLock};

use crate::enrollment::{
EnrolledFeature, EnrolledFeatureConfig, ExperimentEnrollment, map_features_by_feature_id,
};
use crate::error::{NimbusError, Result, warn};
use crate::stateful::enrollment::get_enrollments;
use crate::stateful::gecko_prefs::GeckoPrefStore;
use crate::stateful::persistence::{Database, StoreId, Writer};
use crate::{EnrolledExperiment, Experiment};

// This module manages an in-memory cache of the database, so that some
// functions exposed by nimbus can return results without blocking on any
// IO. Consumers are expected to call our public `update()` function whenever
Expand Down
21 changes: 9 additions & 12 deletions components/nimbus/src/stateful/enrollment.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::enrollment::Participation;
use crate::enrollment::{
EnrollmentChangeEvent, EnrollmentChangeEventType, EnrollmentsEvolver, ExperimentEnrollment,
map_enrollments,
};
use crate::error::{Result, debug, warn};
use crate::stateful::gecko_prefs::GeckoPrefStore;
use crate::stateful::gecko_prefs::PrefUnenrollReason;
use crate::stateful::persistence::{
DB_KEY_EXPERIMENT_PARTICIPATION, DB_KEY_ROLLOUT_PARTICIPATION,
DEFAULT_EXPERIMENT_PARTICIPATION, DEFAULT_ROLLOUT_PARTICIPATION,
};
use crate::{
EnrolledExperiment, EnrollmentStatus, Experiment,
enrollment::{
EnrollmentChangeEvent, EnrollmentChangeEventType, EnrollmentsEvolver, ExperimentEnrollment,
map_enrollments,
},
error::{Result, debug, warn},
stateful::{
gecko_prefs::PrefUnenrollReason,
persistence::{Database, Readable, StoreId, Writer},
},
};
use crate::stateful::persistence::{Database, Readable, StoreId, Writer};
use crate::{EnrolledExperiment, EnrollmentStatus, Experiment};

impl EnrollmentsEvolver<'_> {
/// Convenient wrapper around `evolve_enrollments` that fetches the current state of experiments,
Expand Down
Loading