-
Notifications
You must be signed in to change notification settings - Fork 230
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
[DISCO-3211] Suggest: move to new remote settings API #6598
base: main
Are you sure you want to change the base?
Conversation
@@ -181,11 +157,23 @@ impl Record { | |||
} | |||
} | |||
|
|||
impl From<Record> for RemoteSettingsRecord { |
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.
cargo clippy said impl From
is preferred over Into
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.
Makes sense, Rust will automatically generate the Into
if you define a From
.
@@ -214,6 +202,15 @@ pub(crate) enum SuggestRecord { | |||
Geonames, | |||
} | |||
|
|||
impl SuggestRecord { |
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 feels a little goofy just so that we can use Record
to get_attachment
, but setting fields
to Map::new( )
also felt weird
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.
Yes, slightly goofy but this makes sense to me.
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 looks great. I had some minor suggestions, but the only real issue is how we land this. I'm marking this Request Changes
just because I think we should land that preparatory PR I mentioned to make dealing with the breaking changes easier.
components/suggest/src/store.rs
Outdated
@@ -98,19 +98,14 @@ impl SuggestStoreBuilder { | |||
} | |||
|
|||
#[handle_error(Error)] | |||
pub fn build(&self) -> SuggestApiResult<Arc<SuggestStore>> { | |||
pub fn build(&self, rs_service: &RemoteSettingsService) -> SuggestApiResult<Arc<SuggestStore>> { |
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.
One thing that we haven't talked about is that this is going to be a breaking change for all applications, and it might not be so simple to fix. I'm not sure they all have started using the new remote settings API and have a RemoteSettingsService
ready to give us.
To make the transition easy, could you open a second PR that changes this signature to something like this:
#[uniffi::method(default(rs_service=None))]
pub fn build(&self, rs_service: Option<Arc<RemoteSettingsService>>)
That PR doesn't need to do actually do anything with rs_service
. The point is to give us a decent way to merge all the changes:
- Merge the above, non-breaking, change.
- Get all consumers to start passing in the
rs_service
- Merge your actual PR, which technically will be a breaking change since
rs_service
is no longer optional, but it shouldn't be much work to fix the consumer apps. Maybe they won't need any changes at all.
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.
remote_settings_server
and remote_settings_bucket_name
can be removed from SuggestStoreBuilder
too.
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.
Actually why not make rs_service
a method on SuggestStoreBuilder
instead of an arg to build
?
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.
std::fs::copy(starter_db_path, &db_path).expect("Error copying starter DB file"); | ||
SuggestStore::new(&db_path.to_string_lossy(), None).expect("Error building store") | ||
SuggestStore::new(&db_path.to_string_lossy(), remote_settings_service) | ||
.expect("Error building store") |
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.
Nice! Thanks for keeping this code up to date.
components/suggest/src/rs.rs
Outdated
}) | ||
} | ||
|
||
fn client_for_collection(&self, collection: Collection) -> &remote_settings::RemoteSettings { | ||
fn client_for_collection(&self, collection: Collection) -> &Arc<RemoteSettingsClient> { |
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.
Nit: this could just be a &RemoteSettingsClient
. The Arc
makes me think it might be cloned to create a new reference, but I don't think you ever do that.
components/suggest/src/rs.rs
Outdated
}; | ||
if last_modified != response.last_modified { | ||
dao.write_cached_rs_data(collection.name(), &response); | ||
let _ = client.sync(); |
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 should be client.sync()?
, that way errors get propagated up.
@@ -181,11 +157,23 @@ impl Record { | |||
} | |||
} | |||
|
|||
impl From<Record> for RemoteSettingsRecord { |
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.
Makes sense, Rust will automatically generate the Into
if you define a From
.
@@ -214,6 +202,15 @@ pub(crate) enum SuggestRecord { | |||
Geonames, | |||
} | |||
|
|||
impl SuggestRecord { |
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.
Yes, slightly goofy but this makes sense to me.
components/suggest/src/rs.rs
Outdated
fn to_json_map(&self) -> Map<String, Value> { | ||
match serde_json::to_value(self) { | ||
Ok(Value::Object(map)) => map, | ||
_ => Map::new(), |
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.
Maybe this branch could be unreachable!()
. I think we can safely say that serde
will always be able to to deserialize to Value::Object
.
93bd3d2
to
4e99448
Compare
I see that there are a couple of PRs that will slightly change this one, I will wait and see when those merge and change accordingly |
4e99448
to
5ddb547
Compare
5ddb547
to
f584af2
Compare
I see that the other PRs are merged, so i rebased and made changes 🙂 |
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.
IIUC we no longer need our RS cache in suggest
, right? And that's why this removes the RS-cache-related methods from SuggestDao
. It looks like rs_cache
is still referenced in schema.rs
, so we'll also need to:
- remove those references
- add a schema migration that removes the
rs_cache
table
I think we need to do this before vendoring, so either in this PR or in a fast follow-up.
components/suggest/src/rs.rs
Outdated
// For now, handle the cache manually. Once 6328 is merged, we should be able to delegate | ||
// this to remote_settings. |
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 comment can be removed.
components/suggest/src/rs.rs
Outdated
match &record.attachment { | ||
Some(a) => Ok(self | ||
Some(_a) => Ok(self |
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.
Nit: Some(_)
components/suggest/src/store.rs
Outdated
@@ -98,19 +98,14 @@ impl SuggestStoreBuilder { | |||
} | |||
|
|||
#[handle_error(Error)] | |||
pub fn build(&self) -> SuggestApiResult<Arc<SuggestStore>> { | |||
pub fn build(&self, rs_service: &RemoteSettingsService) -> SuggestApiResult<Arc<SuggestStore>> { |
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.
components/suggest/src/rs.rs
Outdated
} | ||
|
||
fn download_attachment(&self, record: &Record) -> Result<Vec<u8>> { | ||
fn download_attachment(&self, record: Record) -> Result<Vec<u8>> { |
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 can remain &Record
AFAICT, no need to pass by value
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.
oh i ran into trouble yesterday and this is my rust newbie solution. get_attachment
expects a &RemoteSettingRecord
and .into()
wasn't helping. Since we're suggesting removing the struct below in a follow up, this would resolve itself?
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.
If you add back the &
in both places in rs.rs
and then fix the errors in the other files, it should work (it does for me). I do think it's worth fixing so we're not unnecessarily creating clones.
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.
let me try that again
@@ -181,11 +157,23 @@ impl Record { | |||
} | |||
} | |||
|
|||
impl From<Record> for RemoteSettingsRecord { | |||
fn from(record: Record) -> Self { |
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.
Could we get a bug/ticket on file for removing our Record
struct?
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.
makes sense it's more or less the same as RemoteSettingsRecord
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.
The key difference is the payload
field. RemoteSettingsRecord
stores a JSON value there, since it doesn't know the specifics of how it's going to be used. suggest::rs::Record
stores the deserialized SuggestRecord
there. So, if a function inputs suggest::rs::Record
it can access the fields more conveniently and it doesn't have to deal with deserialization errors.
It's still a good idea and I'm pretty sure there's a way to remove some code duplication. Maybe RemoteSettingsRecord
could be generic over its payload
field. It's just not going to be a trivial change.
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.
created a jira in our maintenance epic for this
components/suggest/src/store.rs
Outdated
})) | ||
} else { | ||
Err(Error::RemoteSettings(RemoteSettingsError::Other { | ||
reason: "Unable to create client".to_string(), |
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.
Im unsure what's the best way to handle this
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.
Yeah this makes sense to me and it's similar to how we return an error if data_path
is none, right above. You could use that as an example to rewrite this without an if
statement:
let rs_service = inner.remote_settings_service.clone().ok_or_else(|| {
Error::RemoteSettings(RemoteSettingsError::Other {
reason: "Unable to create client".to_string(),
})
})?;
Ok(Arc::new(SuggestStore {
inner: SuggestStoreInner::new(
data_path,
extensions_to_load,
SuggestRemoteSettingsClient::new(&rs_service)?,
),
}))
I'll need to defer to @bendk if all this is kosher or not w/r/t Arc
. SuggestRemoteSettingsClient
should probably take an Arc<RemoteSettingsService>
instead of &RemoteSettingsService
, right? Like how SuggestStore
does.
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.
The error message should be something like "remote_settings_service not specified"
(similar to the data_path
error message)
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.
Agreed that that error message would be better. I think everything else is fine.
It's okay that SuggestRemoteStetingsClient::new
. inputs &RemoteSettingsService
, since it only uses that that to call make_client()
, then stores the returned Arc<RemoteSettingsClient>
instances. In general, I think Rust is going to keep us honest here and throw up compile errors if we do something wrong.
okie doke, i think i've addressed the latest feedback |
components/suggest/src/schema.rs
Outdated
@@ -616,6 +611,12 @@ impl ConnectionInitializer for SuggestConnectionInitializer<'_> { | |||
)?; | |||
Ok(()) | |||
} | |||
32 => { | |||
// Drop rs_cache since it's no longer needed. | |||
clear_database(tx)?; |
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.
No need to clear the DB I don't think?
@@ -819,11 +815,6 @@ PRAGMA user_version=16; | |||
0, | |||
"ingested_records should be empty" | |||
); | |||
assert_eq!( |
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.
A few code comments in this function (including the function's doc comment) talk about rs_cache
so could you update those too please?
components/suggest/src/store.rs
Outdated
// When #6607 lands, this will set the remote settings service. | ||
// For now, it just exists so we can move consumers over to the new API ahead of time. |
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 comment can be removed but I'll defer to @bendk on if/how this patch breaks mobile consumers.
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.
Yeah, this comment can be removed. Assuming we get mobile consumers using the new API from #6607 ahead of time, then there's no breakage.
components/suggest/src/store.rs
Outdated
})) | ||
} else { | ||
Err(Error::RemoteSettings(RemoteSettingsError::Other { | ||
reason: "Unable to create client".to_string(), |
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.
Yeah this makes sense to me and it's similar to how we return an error if data_path
is none, right above. You could use that as an example to rewrite this without an if
statement:
let rs_service = inner.remote_settings_service.clone().ok_or_else(|| {
Error::RemoteSettings(RemoteSettingsError::Other {
reason: "Unable to create client".to_string(),
})
})?;
Ok(Arc::new(SuggestStore {
inner: SuggestStoreInner::new(
data_path,
extensions_to_load,
SuggestRemoteSettingsClient::new(&rs_service)?,
),
}))
I'll need to defer to @bendk if all this is kosher or not w/r/t Arc
. SuggestRemoteSettingsClient
should probably take an Arc<RemoteSettingsService>
instead of &RemoteSettingsService
, right? Like how SuggestStore
does.
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.
Thanks Tif!
components/suggest/src/store.rs
Outdated
@@ -578,8 +569,7 @@ where | |||
// For each collection, fetch all records | |||
for (collection, record_types) in record_types_by_collection { | |||
breadcrumb!("Ingesting collection {}", collection.name()); | |||
let records = | |||
write_scope.write(|dao| self.settings_client.get_records(collection, dao))?; | |||
let records = write_scope.write(|_| self.settings_client.get_records(collection))?; |
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.
let records = self.settings_client.get_records(collection)?;
No need for the write scope anymore since we don't need to write to the DB when getting records. (Sorry for not catching that before)
components/suggest/src/store.rs
Outdated
let records = writer | ||
.write(|dao| { | ||
.write(|_| { | ||
self.settings_client | ||
.get_records(ingest_record_type.collection(), dao) | ||
.get_records(ingest_record_type.collection()) | ||
}) | ||
.unwrap(); |
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.
Here too:
let records = self
.settings_client
.get_records(ingest_record_type.collection())
.unwrap();
Pull Request checklist
[ci full]
to the PR title.Branch builds: add
[firefox-android: branch-name]
to the PR title.