Open
Description
Motivation
It is currently impossible to synchronously run code into a @globalActor
context from pre-concurrency APIs that we know are running in such task executor.
For example:
@globalActor actor ServiceActor: Actor {
let queue: DispatchSerialQueue
let unownedExecutor: UnownedSerialExecutor
init(identifier: String) {
self.queue = DispatchSerialQueue(label: identifier + ".queue")
self.unownedExecutor = self.queue.asUnownedSerialExecutor()
}
static let shared = ServiceActor(identifier: XPC_ID)
}
At some point I have a pre-concurrency handler which is assured to be called in the previously defined DispatchQueue
.
try XPCListener(service: identifier, targetQueue: ServiceActor.shared.queue, options: .inactive) { _ in
// I know here I am in the `ServiceActor` context.
// I would like to do something like ServiceActor.assumeIsolated
handleSession(request: $0)
}
@ServiceActor func handleSession(request: ...) {}
Proposed solution
Ideally @globalActor
s support static assumeIsolated(_:)
functions.
Alternatives considered
Currently I am following a similar pattern that the standard library uses:
static func assumeIsolated<O, E: Swift.Error>(
_ operation: @ServerActor () throws(E) -> sending O
) throws(E) -> sending O {
typealias NoActor = () throws(E) -> sending O
preconditionIsolated()
return try withoutActuallyEscaping(operation) { operation throws(E) -> sending O in
try unsafeBitCast(operation, to: NoActor.self)()
}
}
Additional information
Filling this "request" was suggested by @ktoso in a Swift forums post/question.