Implement customization point for `enqueue`

# Motivation
The default implementation of `SerialExecutor` for `EventLoop`s causes a lot of allocations that's why we added a new customization point to allow `EventLoop`s to implement fast paths.

# Modification
This PR adds the customization point to `NIOTSEventLoop`.
This commit is contained in:
Franz Busch 2023-10-09 13:57:01 +01:00
parent 0561bee80c
commit 33620e3181
3 changed files with 37 additions and 2 deletions

View File

@ -21,7 +21,7 @@ let package = Package(
.library(name: "NIOTransportServices", targets: ["NIOTransportServices"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "2.58.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.60.0"),
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.2"),
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0"),
],

View File

@ -262,4 +262,21 @@ extension NIOTSEventLoop {
assert(oldChannel != nil)
}
}
// MARK: SerialExecutor conformance
#if compiler(>=5.9)
@available(macOS 14.0, *)
extension NIOTSEventLoop: NIOSerialEventLoopExecutor {
func enqueue(_ job: consuming ExecutorJob) {
let unownedJob = UnownedJob(job)
if let executorQueue = self.taskQueue as? _DispatchSerialExecutorQueue {
executorQueue.enqueue(unownedJob)
} else {
self.execute {
unownedJob.runSynchronously(on: self.asUnownedSerialExecutor())
}
}
}
}
#endif
#endif

View File

@ -19,9 +19,20 @@ import NIOCore
import NIOConcurrencyHelpers
import NIOTransportServices
@available(macOS 14.0, iOS 17.0, watchOS 10.0, tvOS 17.0, *)
private final actor CustomActor {
let executor = NIOTSEventLoopGroup(loopCount: 1).next().executor
nonisolated var unownedExecutor: UnownedSerialExecutor {
return executor.asUnownedSerialExecutor()
}
func foo() -> String {
return "foo"
}
}
@available(OSX 10.14, iOS 12.0, tvOS 12.0, *)
class NIOTSEventLoopTest: XCTestCase {
final class NIOTSEventLoopTest: XCTestCase {
func testIsInEventLoopWorks() throws {
let group = NIOTSEventLoopGroup()
let loop = group.next()
@ -149,5 +160,12 @@ class NIOTSEventLoopTest: XCTestCase {
}
}
}
@available(macOS 14.0, iOS 17.0, tvOS 17.0, *)
func testSerialExecutor() async {
let actor = CustomActor()
let result = await actor.foo()
XCTAssertEqual(result, "foo")
}
}
#endif