Hi everyone. Thanks to everyone who participated in the review for SE-0392, Custom Actor Executors. The Language Workgroup accepts the proposal in principle, but has decided to return the proposal for revision. There are some relatively minor changes to the proposed API that we would like to see explored in a second round of review:
-
The proposal offers a function
assertOnActorExecutor(_: Actor)
to assert that code is currently executing on the executor for a given actor instance, and some reviewers found the name confusing as to whether the actor instance itself or its sharedUnownedExecutor reference ought to be passed. The Language Workgroup wants to suggest turning this standalone function into a method, if possible. Variants of the method could be provided including an instance method for instantiated actors, a static method for global actors, and an instance method for serial executors, allowing for code to read naturally in any of the three cases. -
There was concern about the use of the common term
Job
as a standard library type, both because it's likely to be frequently shadowed byJob
declarations in other modules, and becauseJob
has similar connotations toTask
, and the presence ofJob
andTask
types together would be likely to confuse some developers. The Language Workgroup expects that code working with custom executors and jobs will be far less common than code that works with tasks, so giving the type a more unique and descriptive name likeExecutorJob
would be appropriate. (If it were possible, the qualified nameExecutor.Job
would be nice, but sinceExecutor
is a protocol, that would mean that every implementation ofExecutor
would end up with aJob
type nested inside it.) -
The proposal defines
Job
as a noncopyable type, which the Language Workgroup agrees is a great use of the new language feature, and the right thing to do. However, we expect that developers are likely to run into limitations given the initial subset of noncopyable type support provided by SE-0390. The proposal states that APIs using theUnownedJob
type, which does not statically enforce single ownership will be deprecated, but we expect that developers may need to useUnownedJob
in the short- to medium-term to express things that are difficult to achieve with a noncopyableJob
. We agree that use ofJob
should be encouraged where possible, but that it should be clear thatUnownedJob
remains available as an escape hatch while the capabilities of noncopyable types continue to develop. -
There was good discussion of what should happen when code asks a distributed actor instance what its executor is. The question doesn't really make sense to ask of a remote actor instance, since the only code that locally executes on its behalf is the nonisolated remote call stub, and it doesn't make sense to try to enqueue additional local work on a remote actor's executor. One possibility would be to have the
unownedExecutor
property of an actor beOptional
, and have distributed actor instances returnnil
, but the Language Workgroup agrees with the proposal's choice not to take this route, since doing so would add friction to code that only works with local actors. Instead of returning a "default" executor, though, the language workgroup would like to see if it's possible to use an executor implementation that raises afatalError
if any code tries to enqueue additional jobs on it. Although it may make sense to ask an arbitrary actor for its executor to log the value as a debugging aid, it is likely a programming mistake to attempt to use that executor reference to enqueue work, so it may be preferable to trap at the attempt rather than to fall back to some default executor, to avoid expectations that the work will actually occur exclusively with work being done on the remote actor instance.
Thank you again to everyone who helped participate in the review!