-
Notifications
You must be signed in to change notification settings - Fork 239
Move nimbus to new RS api #6662
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -77,34 +77,31 @@ public extension Nimbus { | |||||||||||||||||||||
/// - Throws `NimbusError` if anything goes wrong with the Rust FFI or in the `NimbusClient` constructor. | ||||||||||||||||||||||
/// | ||||||||||||||||||||||
static func create( | ||||||||||||||||||||||
_ server: NimbusServerSettings?, | ||||||||||||||||||||||
appSettings: NimbusAppSettings, | ||||||||||||||||||||||
coenrollingFeatureIds: [String] = [], | ||||||||||||||||||||||
dbPath: String, | ||||||||||||||||||||||
resourceBundles: [Bundle] = [Bundle.main], | ||||||||||||||||||||||
enabled: Bool = true, | ||||||||||||||||||||||
userDefaults: UserDefaults? = nil, | ||||||||||||||||||||||
errorReporter: @escaping NimbusErrorReporter = defaultErrorReporter, | ||||||||||||||||||||||
recordedContext: RecordedContext? = nil | ||||||||||||||||||||||
recordedContext: RecordedContext? = nil, | ||||||||||||||||||||||
remoteSettingsService: RemoteSettingsService? = nil, | ||||||||||||||||||||||
collectionName: String? = nil | ||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will require an associated change here application-services/components/nimbus/ios/Nimbus/NimbusBuilder.swift Lines 262 to 271 in b56ecd3
|
||||||||||||||||||||||
) throws -> NimbusInterface { | ||||||||||||||||||||||
guard enabled else { | ||||||||||||||||||||||
return NimbusDisabled.shared | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
let context = Nimbus.buildExperimentContext(appSettings) | ||||||||||||||||||||||
let remoteSettings = server.map { server -> RemoteSettingsConfig in | ||||||||||||||||||||||
RemoteSettingsConfig( | ||||||||||||||||||||||
collectionName: server.collection, | ||||||||||||||||||||||
server: .custom(url: server.url.absoluteString) | ||||||||||||||||||||||
) | ||||||||||||||||||||||
} | ||||||||||||||||||||||
|
||||||||||||||||||||||
let nimbusClient = try NimbusClient( | ||||||||||||||||||||||
appCtx: context, | ||||||||||||||||||||||
recordedContext: recordedContext, | ||||||||||||||||||||||
coenrollingFeatureIds: coenrollingFeatureIds, | ||||||||||||||||||||||
dbpath: dbPath, | ||||||||||||||||||||||
remoteSettingsConfig: remoteSettings, | ||||||||||||||||||||||
metricsHandler: GleanMetricsHandler() | ||||||||||||||||||||||
metricsHandler: GleanMetricsHandler(), | ||||||||||||||||||||||
remoteSettingsService: remoteSettingsService, | ||||||||||||||||||||||
collectionName: collectionName | ||||||||||||||||||||||
) | ||||||||||||||||||||||
|
||||||||||||||||||||||
return Nimbus( | ||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,12 @@ | ||
[External="remote_settings"] | ||
typedef record RemoteSettingsConfig; | ||
typedef interface RemoteSettingsService; | ||
|
||
[External="remote_settings"] | ||
typedef enum RemoteSettingsServer; | ||
|
||
[External="remote_settings"] | ||
typedef record RemoteSettingsRecord; | ||
|
||
dictionary CalculatedAttributes { | ||
i32? days_since_install; | ||
i32? days_since_update; | ||
|
@@ -147,8 +150,9 @@ interface NimbusClient { | |
RecordedContext? recorded_context, | ||
sequence<string> coenrolling_feature_ids, | ||
string dbpath, | ||
RemoteSettingsConfig? remote_settings_config, | ||
MetricsHandler metrics_handler | ||
MetricsHandler metrics_handler, | ||
string? collection_name, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe the collection name could be live in the nimbus code, but I'm not sure. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My suggestion would be that it lives in the client code, actually. |
||
RemoteSettingsService? remote_settings_service | ||
); | ||
|
||
/// Initializes the database and caches enough information so that the | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
// file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
|
||
use crate::{defaults::Defaults, enrollment::ExperimentMetadata, NimbusError, Result}; | ||
use remote_settings::RemoteSettingsRecord; | ||
use serde_derive::*; | ||
use serde_json::{Map, Value}; | ||
use std::collections::HashSet; | ||
|
@@ -102,40 +103,28 @@ impl ExperimentMetadata for Experiment { | |
} | ||
} | ||
|
||
pub fn parse_experiments(payload: &str) -> Result<Vec<Experiment>> { | ||
// We first encode the response into a `serde_json::Value` | ||
// to allow us to deserialize each experiment individually, | ||
// omitting any malformed experiments | ||
let value: Value = match serde_json::from_str(payload) { | ||
Ok(v) => v, | ||
Err(e) => { | ||
return Err(NimbusError::JSONError( | ||
"value = nimbus::schema::parse_experiments::serde_json::from_str".into(), | ||
e.to_string(), | ||
)) | ||
} | ||
}; | ||
let data = value | ||
.get("data") | ||
.ok_or(NimbusError::InvalidExperimentFormat)?; | ||
pub fn parse_experiments(records: Vec<RemoteSettingsRecord>) -> Result<Vec<Experiment>> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this can continue to input a string and parse it like before. That should reduce the number of test changes needed. Something like this should work:
|
||
// XXX: In the future it would be nice if this lxived in its own versioned crate so that | ||
// the schema could be decoupled from the sdk so that it can be iterated on while the | ||
// sdk depends on a particular version of the schema through the Cargo.toml. | ||
let mut res = Vec::new(); | ||
for exp in data | ||
.as_array() | ||
.ok_or(NimbusError::InvalidExperimentFormat)? | ||
{ | ||
// XXX: In the future it would be nice if this lived in its own versioned crate so that | ||
// the schema could be decoupled from the sdk so that it can be iterated on while the | ||
// sdk depends on a particular version of the schema through the Cargo.toml. | ||
match serde_json::from_value::<Experiment>(exp.clone()) { | ||
Ok(exp) => res.push(exp), | ||
Err(e) => { | ||
log::trace!("Malformed experiment data: {:#?}", exp); | ||
log::warn!( | ||
"Malformed experiment found! Experiment {}, Error: {}", | ||
exp.get("id").unwrap_or(&serde_json::json!("ID_NOT_FOUND")), | ||
e | ||
); | ||
for record in records { | ||
if let Some(Value::Array(exp_data)) = record.fields.get("data") { | ||
for entry in exp_data { | ||
match serde_json::from_value::<Experiment>(entry.clone()) { | ||
Ok(exp) => res.push(exp), | ||
Err(e) => { | ||
log::trace!("Malformed experiment data: {:#?}", record.fields); | ||
log::warn!( | ||
"Malformed experiment found! Experiment {}, Error: {}", | ||
record.id, | ||
e | ||
); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. todo: tif this is about the array, ref 122 |
||
} | ||
} else { | ||
return Err(NimbusError::InvalidExperimentFormat); | ||
} | ||
} | ||
Ok(res) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will require an associated change in the constructor use here
application-services/components/nimbus/android/src/main/java/org/mozilla/experiments/nimbus/NimbusBuilder.kt
Lines 221 to 232 in b56ecd3
As well as in a number of tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's you're feeling on how hard it's going to be to get a
RemoteSettingsService
to pass to the constructor on the firefox-android side?If I traced through the code correctly, I think it just means moving the RemoteSettingsService val above the Nimbus components val. That seems easy enough, but I'm slightly worried that there are special requirements for Nimbus startup that could cause problems.
Similarly, do you foresee any issues on focus or ios?