Skip to content

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

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Move nimbus to new RS api #6662

wants to merge 2 commits into from

Conversation

tiftran
Copy link
Contributor

@tiftran tiftran commented Mar 24, 2025

Pull Request checklist

  • Breaking changes: This PR follows our breaking change policy
    • This PR follows the breaking change policy:
      • This PR has no breaking API changes, or
      • There are corresponding PRs for our consumer applications that resolve the breaking changes and have been approved
  • Quality: This PR builds and tests run cleanly
    • Note:
      • For changes that need extra cross-platform testing, consider adding [ci full] to the PR title.
      • If this pull request includes a breaking change, consider cutting a new release after merging.
  • Tests: This PR includes thorough tests or an explanation of why it does not
  • Changelog: This PR includes a changelog entry in CHANGELOG.md or an explanation of why it does not need one
    • Any breaking changes to Swift or Kotlin binding APIs are noted explicitly
  • Dependencies: This PR follows our dependency management guidelines
    • Any new dependencies are accompanied by a summary of the due diligence applied in selecting them.

Branch builds: add [firefox-android: branch-name] to the PR title.

@tiftran tiftran changed the title Move to new RS api Move nimbus to new RS api Mar 24, 2025
Copy link
Contributor

@bendk bendk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good overall, I left a few suggestions mostly just to try to reduce the amount of changes needed. The biggest question in my mind is how easy it is for consumers to pass the RemoteSettingsService that they're passing to the suggest/relavency constructors. In theory it should be pretty easy, but I know consumers often want to initialize nimbus very early on in the process which could complicate things.

e
);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should return NimbusError::InvalidExperimentFormat if the if let doesn't match.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

todo: tif this is about the array, ref 122

RemoteSettingsConfig? remote_settings_config,
MetricsHandler metrics_handler
MetricsHandler metrics_handler,
string? collection_name,
Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion would be that it lives in the client code, actually.

)
}

val remoteSettingsService = RemoteSettingsService(dataDir, remoteSettingsConfig)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should input the RemoteSettingsService in the constructor. That way all the remote-settings consumers can share the same service.

You may want to do the same dance we did with the other components, where we add an optional argument in the constructor in a separate patch. I'm not so sure that's needed though now that we've already done a few of these. Maybe we could just introduce the breaking change as long as there's a PR to fix it ready.

let data = value
.get("data")
.ok_or(NimbusError::InvalidExperimentFormat)?;
pub fn parse_experiments(records: Vec<RemoteSettingsRecord>) -> Result<Vec<Experiment>> {
Copy link
Contributor

Choose a reason for hiding this comment

The 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:

pub fn parse_experiments(payload: &str) -> Result<Vec<Experiment>> {
  let records: Vec<RemoteSettingsRecord> = match serde_json::from_str(records) {
    Ok(v) => v,
    Err(e) => {
        return Err(NimbusError::JSONError(
            "value = nimbus::schema::parse_experiments::serde_json::from_str".into(),
            e.to_string(),
        ))
  };
  // .. same as before
}

@tiftran tiftran force-pushed the nimbus-rs branch 4 times, most recently from ef7bd07 to 990d9e2 Compare April 1, 2025 06:24
@tiftran tiftran force-pushed the nimbus-rs branch 4 times, most recently from a1279cb to 06dd7dc Compare April 9, 2025 19:21
Copy link
Member

@jeddai jeddai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done a cursory review, and this is a great start! There's quite a bit more that will need to be added for the Kotlin/Swift side of things. If you'd like any further guidance on that I'm more than happy to help — you're welcome to throw something on my calendar or I can provide answers to any questions you have here.

)
}

val collectionName = it.collection
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the call to server?.let has been removed, it no longer refers to an object. I think the collectionName would need to be a parameter of the constructor moving forward

@@ -68,7 +67,7 @@ open class Nimbus(
override val prefs: SharedPreferences? = null,
appInfo: NimbusAppInfo,
coenrollingFeatureIds: List<String>,
server: NimbusServerSettings?,
remoteSettingsService: RemoteSettingsService,
Copy link
Member

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

override fun newNimbus(appInfo: NimbusAppInfo, serverSettings: NimbusServerSettings?) =
Nimbus(
context,
appInfo = appInfo,
prefs = sharedPreferences,
coenrollingFeatureIds = getCoenrollingFeatureIds(),
server = serverSettings,
deviceInfo = createDeviceInfo(),
delegate = createDelegate(),
observer = createObserver(),
recordedContext = recordedContext,
)

As well as in a number of tests

Copy link
Contributor

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?

recordedContext: RecordedContext? = nil
recordedContext: RecordedContext? = nil,
remoteSettingsService: RemoteSettingsService? = nil,
collectionName: String? = nil
Copy link
Member

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 here

func newNimbus(_ appInfo: NimbusAppSettings, serverSettings: NimbusServerSettings?) throws -> NimbusInterface {
try Nimbus.create(serverSettings,
appSettings: appInfo,
coenrollingFeatureIds: getCoenrollingFeatureIds(),
dbPath: dbFilePath,
resourceBundles: resourceBundles,
userDefaults: userDefaults,
errorReporter: errorReporter,
recordedContext: recordedContext)
}

RemoteSettingsConfig? remote_settings_config,
MetricsHandler metrics_handler
MetricsHandler metrics_handler,
string? collection_name,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion would be that it lives in the client code, actually.

@@ -3,12 +3,12 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

use crate::stateful::persistence::{Database, StoreId};
use crate::AppContext;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this change necessary?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants