[Concurrency] Passing classes between actors

There seems to be an open question about how to handle passing mutable state between actors (or possibly just disallowing it). I have a germ of an idea, and I thought I would share in case it triggers a more fully formed idea in someone.

We should have an extremely easy way to wrap a bit of mutable state in a bubble of the actor that owns it… or rather, we should be able to effortlessly create a proxy to mutable state within an actor (either objects, global properties, or closures) for sharing with another actor. For objects, the proxy would basically convert method calls to asynchronous messages. In my mind, the wrapper would hold a reference to the actor’s internal queue, and would forward the message to the object/closure within that queue, then asynchronously return the value (if any) to the calling actor.

Note that this is different than having properties/methods on the actor itself, since the wrapper/proxy might not be shared publicly, and it can be passed around like an object/closure. It allows a bunch of patterns that aren’t possible otherwise. For example, I could ask an actor for a callback closure to call when something has been completed… and the callback that I receive might be unique to me, which allows the actor to field multiple requests asynchronously/independently (Instead of having to track state internally, it can just use the closure to clean up).

Thoughts?

Thanks,
Jon

As you say, this is effectively a closure around a reference to a state with a guarantee that it will only be touched in the context of the proper actor. I’m not exactly sure how this sketch of an idea would work, but I think that something like it is very likely to follow from the basic design.

That’s sort of the appeal of starting from a minimal design: with the basics in place, we can look at the pain points in practice, and figure out how to expand them out to support common patterns like this. What you describe seems very likely to me, and I hope it is something we can express with a library rather than a language feature.

-Chris

···

On Aug 23, 2017, at 2:18 PM, Jonathan Hull via swift-evolution <swift-evolution@swift.org> wrote:

There seems to be an open question about how to handle passing mutable state between actors (or possibly just disallowing it). I have a germ of an idea, and I thought I would share in case it triggers a more fully formed idea in someone.

We should have an extremely easy way to wrap a bit of mutable state in a bubble of the actor that owns it… or rather, we should be able to effortlessly create a proxy to mutable state within an actor (either objects, global properties, or closures) for sharing with another actor. For objects, the proxy would basically convert method calls to asynchronous messages. In my mind, the wrapper would hold a reference to the actor’s internal queue, and would forward the message to the object/closure within that queue, then asynchronously return the value (if any) to the calling actor.

Note that this is different than having properties/methods on the actor itself, since the wrapper/proxy might not be shared publicly, and it can be passed around like an object/closure. It allows a bunch of patterns that aren’t possible otherwise. For example, I could ask an actor for a callback closure to call when something has been completed… and the callback that I receive might be unique to me, which allows the actor to field multiple requests asynchronously/independently (Instead of having to track state internally, it can just use the closure to clean up).