diff --git a/Package.swift b/Package.swift index ae0e8a5d..22fd0508 100644 --- a/Package.swift +++ b/Package.swift @@ -2,7 +2,9 @@ import PackageDescription #if compiler(>=6.1) -let swiftSettings: [SwiftSetting] = [] +let swiftSettings: [SwiftSetting] = [ + .enableUpcomingFeature("NonisolatedNonsendingByDefault") +] #else let swiftSettings: [SwiftSetting] = [ // Sadly the 6.0 compiler concurrency checker finds false positives. diff --git a/Sources/ConnectionPoolModule/ConnectionPool.swift b/Sources/ConnectionPoolModule/ConnectionPool.swift index 40d52a5a..32836967 100644 --- a/Sources/ConnectionPoolModule/ConnectionPool.swift +++ b/Sources/ConnectionPoolModule/ConnectionPool.swift @@ -578,20 +578,20 @@ protocol TaskGroupProtocol { // We need to call this `addTask_` because some Swift versions define this // under exactly this name and others have different attributes. So let's pick // a name that doesn't clash anywhere and implement it using the standard `addTask`. - mutating func addTask_(operation: @escaping @Sendable () async -> Void) + mutating func addTask_(operation: @isolated(any) @escaping @Sendable () async -> Void) } @available(macOS 14.0, iOS 17.0, tvOS 17.0, watchOS 10.0, *) extension DiscardingTaskGroup: TaskGroupProtocol { @inlinable - mutating func addTask_(operation: @escaping @Sendable () async -> Void) { + mutating func addTask_(operation: @isolated(any) @escaping @Sendable () async -> Void) { self.addTask(priority: nil, operation: operation) } } extension TaskGroup: TaskGroupProtocol { @inlinable - mutating func addTask_(operation: @escaping @Sendable () async -> Void) { + mutating func addTask_(operation: @isolated(any) @escaping @Sendable () async -> Void) { self.addTask(priority: nil, operation: operation) } } diff --git a/Sources/PostgresNIO/New/PostgresNotificationSequence.swift b/Sources/PostgresNIO/New/PostgresNotificationSequence.swift index d8f525eb..de4c7b5a 100644 --- a/Sources/PostgresNIO/New/PostgresNotificationSequence.swift +++ b/Sources/PostgresNIO/New/PostgresNotificationSequence.swift @@ -6,18 +6,30 @@ public struct PostgresNotification: Sendable { public struct PostgresNotificationSequence: AsyncSequence, Sendable { public typealias Element = PostgresNotification - let base: AsyncThrowingStream + let base: AsyncThrowingStream public func makeAsyncIterator() -> AsyncIterator { AsyncIterator(base: self.base.makeAsyncIterator()) } public struct AsyncIterator: AsyncIteratorProtocol { - var base: AsyncThrowingStream.AsyncIterator + var base: AsyncThrowingStream.AsyncIterator + #if compiler(>=6.2) + @concurrent public mutating func next() async throws -> Element? { try await self.base.next() } + #else + public mutating func next() async throws -> Element? { + try await self.base.next() + } + #endif + + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + public mutating func next(isolation actor: isolated (any Actor)?) async throws(Self.Failure) -> Element? { + try await self.base.next(isolation: actor) + } } } diff --git a/Sources/PostgresNIO/New/PostgresRowSequence.swift b/Sources/PostgresNIO/New/PostgresRowSequence.swift index 3936b51e..25c1bb4a 100644 --- a/Sources/PostgresNIO/New/PostgresRowSequence.swift +++ b/Sources/PostgresNIO/New/PostgresRowSequence.swift @@ -31,6 +31,7 @@ public struct PostgresRowSequence: AsyncSequence, Sendable { extension PostgresRowSequence { public struct AsyncIterator: AsyncIteratorProtocol { public typealias Element = PostgresRow + public typealias Failure = any Error let backing: BackingSequence.AsyncIterator @@ -43,7 +44,9 @@ extension PostgresRowSequence { self.columns = columns } - public mutating func next() async throws -> PostgresRow? { + #if compiler(>=6.2) + @concurrent + public mutating func next() async throws -> Element? { if let dataRow = try await self.backing.next() { return PostgresRow( data: dataRow, @@ -53,6 +56,36 @@ extension PostgresRowSequence { } return nil } + #else + public mutating func next() async throws -> Element? { + if let dataRow = try await self.backing.next() { + return PostgresRow( + data: dataRow, + lookupTable: self.lookupTable, + columns: self.columns + ) + } + return nil + } + #endif + + @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) + public mutating func next(isolation actor: isolated (any Actor)?) async throws(Self.Failure) -> PostgresRow? { + // Since the underlying NIOThrowingAsyncSequenceProducer.AsyncIterator + // does not supported the next(isolation:) call yet, we will hop here back and forth. + struct UnsafeTransfer: @unchecked Sendable { + var backing: BackingSequence.AsyncIterator + } + let unsafeTransfer = UnsafeTransfer(backing: self.backing) + if let dataRow = try await unsafeTransfer.backing.next() { + return PostgresRow( + data: dataRow, + lookupTable: self.lookupTable, + columns: self.columns + ) + } + return nil + } } }