How to “ObjectContext” with Swift 6 concurrency

I liked naming @isolated(any) / @isolated(caller) - if I understood correctly its purpose - from here. Totally agree that Swift missing that level of isolation control, even with @MainActor in Apple's ecosystem, if you do not want simply mark everything with it, you have not so much options.

From my understanding, there is not so much cases when you need to make something an actor, if as you described, one task owns-one task works with it, is the only way you are going to work with it. So making each time some type an actor seems wrong.

1 Like

The reason why isolating a non-Sendable type to an actor instance dynamically is different and more complicated than global actor isolation is because it is inherently value dependent. To support isolating an entire non-Sendable type to a specific actor instance, we need some form of value dependent types in order to know statically that calls do not cross an isolation boundary, or you need to work with the non-Sendable value as if the isolated actor value is completely opaque, meaning you always need to interact with it asynchronously. Interacting with the non-Sendable value asynchronously is fine for your use case here, but it's not for many of the other use cases involving non-Sendable types that folks are struggling with. In any case, the discussions around the idea to isolated entire non-Sendable types to actor values is happening in Isolation Assumptions.

I'm not suggesting making every type into an actor, but as soon as you start trying to parallelize work over non-Sendable types, you're going to run into problems because data isolation requires the values used in those separate tasks to be Sendable. Using an actor directly is one common way to turn a bag of mutable state into something that is Sendable that you can use inside two different tasks that run on the global concurrent pool in parallel. Isolating the type to something else, be that a global actor or a specific actor value, is another way to turn a bag of mutable state into something that is Sendable.

1 Like

I didn't mean that there were suggestions to do that :slight_smile:

The problem I often bump into is that the majority of the types are fine being non-sendable as long as they accessed within one isolation domain, allowing parallelism even will complicate them from some point of view. So I do not mind which exact isolation domain they will be accessed from, even more - I do not want to restrict the type itself to any isolation domain. Therefore, I would prefer to avoid using global actors isolation. Maybe that is a wrong strategy, concurrency is rather new concept to me, and I am still trying to figure out a better way to use it and organise apps. All these discussions helps a lot.

2 Likes

This is a fair point, and I actually double checked my claim before I posted it because I wasn't sure whether async let attempted to do some kind of fancy inference for the isolation of the expression it will evaluate. It seems feasible to allow that; the compiler already has a mechanism for inferring the required isolation for an expression.

2 Likes