-
Notifications
You must be signed in to change notification settings - Fork 235
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
Allow [Threadsafe] interfaces access to Arc<Self>
#417
Comments
…ch takes an `Arc::clone(self)` Intent is a new attribute is added to such methods (and the method must be on a `[ThreadSafe]` interface). I've chosen `[SomethingSomethingArc]` as the attribute name :) I attempted to change things so handle_map.rs no longer does the ref-deref `&*` magic but instead delegates that to the macros, which only does it if the new attribute exists. This *nearly* works, but has unintended consequences I don't yet understand (ie, the non-threadsafe generated code is using `&*obj` which makes no sense at this hour).
I haven't thought about this very deeply, but high-level, I'm concerned about leaking an incidental implementation of uniffi in this way. We happen to currently use an Again without thinking very deeply, I wonder if it would be possible to invert the responsibility here, and have a way for you to declare that your interface is already inside an |
Yes, good point. Off the top of my head, maybe unifying (ha!) what constructors return and what I'm trying to achieve here - ie, defining what |
I should also say, I'm not prepared to rule out such leakage entirely - for example in the hand-written bindings for places etc I believe we have some sort of
I will be really pleased if we come up with another name for a thing that keeps showing up in conversations in the same way that "sync up (ha!)" has been doing for our team for years 😆 |
It occurs to me in the light of day, that So...maybe I wouldn't actually be too upset if we "leaned in" to the use of |
Another option might be to allow the UDL to somehow say "I want an |
(OTOH though, I think being opinionated here is fine - there's no need for us to support theoretical future use-cases that will probably never exist) |
…manager. 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<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)
For clarity, I'm not sure I understand the problem space enough to make an informed comment. I think this might be worth probing more deeply in a synchronous setting. |
Cross-linking for reference, it turns out that when I said "wouldn't be too upset" what I actually meant was "am about to go on a deep dive about making @mhammond, I think what I'd proposing there is a generalization of what you're talking about here, and if we like the general direction we could consider some sort of
Also, +💯 to talking it through in a synchronous setting if we feel like there's something here we want to move on. |
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)
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)
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)
#3935) 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)
I believe we have broad agreement that what's being requested here is a subset of what we'll implement as a result of #419, so I'm going to close this issue out. |
We've a use-case where it would be ideal to have access to a clone of the
Arc<Self>
stored in theArcHandleMap
.The motivation here is for an app-services component to register with the "sync manager". Without going into too much detail about the "spelling", think something like:
makes sense, where we call something with the signature:
fn register_with_something_external(self: Arc<Self>) { ... }
which leverages "method receivers". The intent is that we can avoid something gross like an
<Arc<Arc<T>>
and instead leverage the fact that uniffi already manages theArc
we need.I'm opening this as a place-holder issue, trying to avoid too much bikeshedding at this stage (hence
[SomethingSomething]
:) - but I welcome it in general.cc @rfk @lougeniaC64 @jhugman @dmose
┆Issue is synchronized with this Jira Task
The text was updated successfully, but these errors were encountered: