Skip to content
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

Wrap the autofill implementation in an Arc<> to help the sync manager. #3935

Merged
merged 1 commit into from
Mar 25, 2021

Conversation

mhammond
Copy link
Member

This patch works-around the lack of the functionality described
in mozilla/uniffi-rs#417.

In short, it splits the store into 2 parts - the
uniffi-exposed "wrapper" and the actual implementation.
This "wrapper" wraps the implementation in an Arc<Mutex>>, so
that it can hand a clone of this Arc<> to the sync manager, so
that it can construct sync engines, causing us to end up with
multiple references to the Store being alive but without any
being actual & references.

(Thinking some more about it, I probably could have done this
slightly differently, and just wrapped the DB itself, but I
ended up somewhat automatically taking this route because this
is what the shape would naturally be if uniffi helped us.
I think passing the entire store around does make more sense
in the longer term anyway (eg, there might be other state beyond
the DB) and is what the other components do, but it does make
this patch bigger than it would otherwise be)

It also makes some changes in the sync manager, really just
enough to convince me that it will work - there will be plenty
of other places that will need similar treatment. I chose to
use the SyncEngine trait exclusively there, which I think makes
sense because ideally we'd use that trait everywhere to avoid the
Sync Manager knowing about the implementation (but it would still
require it to link to all those crates, so that's just a
code-simplicity issue)

@mhammond
Copy link
Member Author

The other thing I meant to say is that as we discussed, this inverts how the sync manager gets engines. Currently, something (ie, Fenix code) needs a reference to both places and the sync manager and calls (something like) manager.set_places(places).

However, in this world, Fenix only needs a reference to the autofill store, and can do just autofill.offer_to_sync_manager() - and magically, a sync manager that's created in the future (or even one already created) will pick it up. I'm obviously open to a better name.

@mhammond
Copy link
Member Author

cc @jhugman for context on that uniffi ticket.

// This is the type that uniffi exposes. It holds an `Arc<Mutex<>>` around the
// actual implementation, because we need access to the `Arc<Mutex<>>` for
// integration with the sync manager. Our UDL also defines us as being
// "ThreadSafe" to we manage our own locking via the `Mutex` - but this means
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: "so" we manage?

// in practice we are actually held via an `Arc<Arc<Mutex<>>>` - but one day
// https://github.com/mozilla/uniffi-rs/issues/417 will give us access to the
// `Arc<>` uniffi owns, which means we can drop this mess entirely (ie, `Store`)
// can then just have a mutex around the DB.
pub struct Store {
Copy link
Contributor

@lougeniaC64 lougeniaC64 Mar 22, 2021

Choose a reason for hiding this comment

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

Does the Store struct need to be public? It looks like StoreImpl is the type that is being imported. Or if both should be public maybe an explanation as to which should be used in what circumstances. There may be an easy explanation that I'm missing, but I could see myself getting confused in the future.

Copy link
Member Author

Choose a reason for hiding this comment

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

This got confusing quickly and sadly they both need to be pub. Store needs to be pub because the sync manager uses it (StoreImpl has the Arc<Store> which we clone and hand to the sync manager, so it gets the Store) and Store needs to be pub because autofill-utils needs it to get the sync engines.

So yeah, this sucks and I added some comments, but hopefully we can get rid of this confusion with the proposed autofill enhancements.

@mhammond
Copy link
Member Author

I'm about to put up a new version that doesn't wrap the entire store in an Arc<Mutex> - instead the store is just wrapped in an Arc<> and the DB remains wrapped in the Mutex it already has. This is both a smaller patch and what's technically needed currently. Later in the future we might need to shuffle this around a bit, but I think this is better.

@codecov-io
Copy link

Codecov Report

Merging #3935 (6f533f2) into main (43c0835) will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##            main   #3935     +/-   ##
=======================================
  Coverage   0.00%   0.00%             
=======================================
  Files        101      75     -26     
  Lines       5903    4439   -1464     
=======================================
+ Misses      5903    4439   -1464     
Impacted Files Coverage Δ
components/autofill/src/db/mod.rs 0.00% <0.00%> (ø)
components/support/guid/src/lib.rs 0.00% <0.00%> (ø)
components/support/types/src/lib.rs 0.00% <0.00%> (ø)
components/support/jwcrypto/src/lib.rs 0.00% <0.00%> (ø)
components/support/sql/src/conn_ext.rs 0.00% <0.00%> (ø)
components/support/sql/src/interrupt.rs 0.00% <0.00%> (ø)
components/support/sync15-traits/src/telemetry.rs 0.00% <0.00%> (ø)
components/autofill/src/sync/mod.rs
components/autofill/src/db/models/mod.rs
...mponents/autofill/src/sync/credit_card/incoming.rs
... and 19 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 43c0835...6f533f2. Read the comment docs.

@mhammond mhammond changed the title Wrap the autofill implementation in an Arc<Mutex<>> to help the sync manager. Wrap the autofill implementation in an Arc<> to help the sync manager. Mar 23, 2021
Copy link
Contributor

@lougeniaC64 lougeniaC64 left a comment

Choose a reason for hiding this comment

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

LGTM!

This patch works-around the lack of the functionlity described
in mozilla/uniffi-rs#417.

In short, it splits the store into 2 parts - the
uniffi-exposed "wrapper" and the actual implementation.
This "wrapper" wraps the implementation in an `Arc<>`, so
that it can hand a clone of this `Arc<>` to the sync manager, so
that it can construct sync engines, causing us to end up with
multiple references to the `Store` being alive but without any
being actual `&` references.

The database itself continues to be wrapped in a `Mutex<>`

It also makes some changes in the sync manager, really just
enough to convince me that it will work - there will be plenty
of other places that will need similar treatment. I chose to
use the `SyncEngine` trait exclusively there, which I think makes
sense because ideally we'd use that trait *everywhere* to avoid the
Sync Manager knowing about the implementation (but it would still
require it to link to all those crates, so that's just a
code-simplicity issue)
@mhammond mhammond merged commit 8784c84 into mozilla:main Mar 25, 2021
@mhammond mhammond deleted the arc-workaround branch March 25, 2021 00:21
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