Skip to content

Commit

Permalink
Fix NIO "Lock" deprecation warnings (#96)
Browse files Browse the repository at this point in the history
* Bump required minimum version of NIO to ensure the renamed types are available.

* NIOConcurrencyHelpers.Lock was renamed to NIOLock. Fixes deprecation warnings.

* Update CI to include public API breakage check and to run code coverage on pushes to main without an extra workflow

* Merge in missing fixes from #95 by @Colgates

* Drop support for Swift 5.4
  • Loading branch information
gwynne authored Nov 3, 2022
1 parent c3329e4 commit 3be4b64
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 45 deletions.
22 changes: 0 additions & 22 deletions .github/workflows/main-codecov.yml

This file was deleted.

5 changes: 4 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
name: test
on: { pull_request: {} }
on:
pull_request: { branches: ['*'] }
push: { branches: ['main'] }

jobs:
unit-tests:
uses: vapor/ci/.github/workflows/run-unit-tests.yml@reusable-workflows
with:
with_coverage: true
with_tsan: true
with_public_api_check: ${{ github.event_name == 'pull_request' }}
8 changes: 5 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.4
// swift-tools-version:5.5
import PackageDescription

let package = Package(
Expand All @@ -11,16 +11,18 @@ let package = Package(
.library(name: "AsyncKit", targets: ["AsyncKit"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "2.10.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.42.0"),
.package(url: "https://github.com/apple/swift-log.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.0.0"),
],
targets: [
.target(name: "AsyncKit", dependencies: [
.product(name: "Logging", package: "swift-log"),
.product(name: "NIO", package: "swift-nio"),
]),
.testTarget(name: "AsyncKitTests", dependencies: [
.target(name: "AsyncKit")
.product(name: "Atomics", package: "swift-atomics"),
.target(name: "AsyncKit"),
]),
]
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import struct Logging.Logger
import NIOConcurrencyHelpers
import struct NIO.TimeAmount
import class NIOConcurrencyHelpers.Lock
import struct NIOConcurrencyHelpers.NIOLock
import Dispatch

/// Holds a collection of connection pools for each `EventLoop` on an `EventLoopGroup`.
Expand Down Expand Up @@ -35,7 +36,7 @@ public final class EventLoopGroupConnectionPool<Source> where Source: Connection
private let logger: Logger

/// Synchronize access.
private let lock: Lock
private let lock: NIOLock

/// If `true`, this connection pool has been closed.
private var didShutdown: Bool
Expand Down Expand Up @@ -207,7 +208,7 @@ public final class EventLoopGroupConnectionPool<Source> where Source: Connection
// - TODO: Does this need to assert "not on any EventLoop", as `EventLoopGroup.syncShutdownGracefully()` does?
var possibleError: Error? = nil
let waiter = DispatchWorkItem {}
let errorLock = Lock()
let errorLock = NIOLock()

self.shutdownGracefully {
if let error = $0 {
Expand Down
17 changes: 9 additions & 8 deletions Tests/AsyncKitTests/ConnectionPoolTests.swift
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Atomics
import AsyncKit
import XCTest
import NIOConcurrencyHelpers
Expand All @@ -18,32 +19,32 @@ final class ConnectionPoolTests: XCTestCase {
XCTAssertEqual(connA.isClosed, false)
let connB = try pool.requestConnection().wait()
XCTAssertEqual(connB.isClosed, false)
XCTAssertEqual(foo.connectionsCreated.load(), 2)
XCTAssertEqual(foo.connectionsCreated.load(ordering: .relaxed), 2)

// try to make a third, but pool only supports 2
var connC: FooConnection?
pool.requestConnection().whenSuccess { connC = $0 }
XCTAssertNil(connC)
XCTAssertEqual(foo.connectionsCreated.load(), 2)
XCTAssertEqual(foo.connectionsCreated.load(ordering: .relaxed), 2)

// release one of the connections, allowing the third to be made
pool.releaseConnection(connB)
XCTAssertNotNil(connC)
XCTAssert(connC === connB)
XCTAssertEqual(foo.connectionsCreated.load(), 2)
XCTAssertEqual(foo.connectionsCreated.load(ordering: .relaxed), 2)

// try to make a third again, with two active
var connD: FooConnection?
pool.requestConnection().whenSuccess { connD = $0 }
XCTAssertNil(connD)
XCTAssertEqual(foo.connectionsCreated.load(), 2)
XCTAssertEqual(foo.connectionsCreated.load(ordering: .relaxed), 2)

// this time, close the connection before releasing it
try connC!.close().wait()
pool.releaseConnection(connC!)
XCTAssert(connD !== connB)
XCTAssertEqual(connD?.isClosed, false)
XCTAssertEqual(foo.connectionsCreated.load(), 3)
XCTAssertEqual(foo.connectionsCreated.load(ordering: .relaxed), 3)
}

func testFIFOWaiters() throws {
Expand Down Expand Up @@ -332,15 +333,15 @@ private struct ErrorDatabase: ConnectionPoolSource {
}

private final class FooDatabase: ConnectionPoolSource {
var connectionsCreated: NIOAtomic<Int>
var connectionsCreated: ManagedAtomic<Int>

init() {
self.connectionsCreated = .makeAtomic(value: 0)
self.connectionsCreated = .init(0)
}

func makeConnection(logger: Logger, on eventLoop: EventLoop) -> EventLoopFuture<FooConnection> {
let conn = FooConnection(on: eventLoop)
_ = self.connectionsCreated.add(1)
self.connectionsCreated.wrappingIncrement(by: 1, ordering: .relaxed)
return conn.eventLoop.makeSucceededFuture(conn)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/AsyncKitTests/EventLoopFutureQueueTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ final class EventLoopFutureQueueTests: XCTestCase {
func testQueue() throws {
let queue = EventLoopFutureQueue(eventLoop: self.eventLoop)
var numbers: [Int] = []
let lock = Lock()
let lock = NIOLock()

let one = queue.append(generator: {
self.eventLoop.slowFuture(1).map { number -> Int in
Expand Down Expand Up @@ -51,7 +51,7 @@ final class EventLoopFutureQueueTests: XCTestCase {
func testAutoclosure() throws {
let queue = EventLoopFutureQueue(eventLoop: self.eventLoop)
var numbers: [Int] = []
let lock = Lock()
let lock = NIOLock()

let one = queue.append(self.eventLoop.slowFuture(1, sleeping: 1).map { num in lock.withLockVoid { numbers.append(num) } })
let two = queue.append(self.eventLoop.slowFuture(2, sleeping: 0).map { num in lock.withLockVoid { numbers.append(num) } })
Expand Down
12 changes: 6 additions & 6 deletions Tests/AsyncKitTests/Future+CollectionTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ final class FutureCollectionTests: XCTestCase {
func testSequencedFlatMapEach() throws {
struct SillyRangeError: Error {}
var value = 0
let lock = Lock()
let lock = NIOLock()
let collection = eventLoop.makeSucceededFuture([1, 2, 3, 4, 5, 6, 7, 8, 9])
let times2 = collection.sequencedFlatMapEach { int -> EventLoopFuture<Int> in
lock.withLock { value = Swift.max(value, int) }
Expand All @@ -126,7 +126,7 @@ final class FutureCollectionTests: XCTestCase {
func testSequencedFlatMapVoid() throws {
struct SillyRangeError: Error {}
var value = 0
let lock = Lock()
let lock = NIOLock()
let collection = eventLoop.makeSucceededFuture([1, 2, 3, 4, 5, 6, 7, 8, 9])
let times2 = collection.sequencedFlatMapEach { int -> EventLoopFuture<Void> in
lock.withLock { value = Swift.max(value, int) }
Expand All @@ -141,7 +141,7 @@ final class FutureCollectionTests: XCTestCase {
func testSequencedFlatMapEachCompact() throws {
struct SillyRangeError: Error {}
var last = ""
let lock = Lock()
let lock = NIOLock()
let collection = self.eventLoop.makeSucceededFuture(["one", "2", "3", "not", "4", "1", "five", "^", "7"])
let times2 = collection.sequencedFlatMapEachCompact { val -> EventLoopFuture<Int?> in
guard let int = Int(val) else { return self.eventLoop.makeSucceededFuture(nil) }
Expand All @@ -157,7 +157,7 @@ final class FutureCollectionTests: XCTestCase {
func testELSequencedFlatMapEach() throws {
struct SillyRangeError: Error {}
var value = 0
let lock = Lock()
let lock = NIOLock()
let collection = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let times2 = collection.sequencedFlatMapEach(on: self.eventLoop) { int -> EventLoopFuture<Int> in
lock.withLock { value = Swift.max(value, int) }
Expand All @@ -172,7 +172,7 @@ final class FutureCollectionTests: XCTestCase {
func testELSequencedFlatMapVoid() throws {
struct SillyRangeError: Error {}
var value = 0
let lock = Lock()
let lock = NIOLock()
let collection = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let times2 = collection.sequencedFlatMapEach(on: self.eventLoop) { int -> EventLoopFuture<Void> in
lock.withLock { value = Swift.max(value, int) }
Expand All @@ -187,7 +187,7 @@ final class FutureCollectionTests: XCTestCase {
func testELSequencedFlatMapEachCompact() throws {
struct SillyRangeError: Error {}
var last = ""
let lock = Lock()
let lock = NIOLock()
let collection = ["one", "2", "3", "not", "4", "1", "five", "^", "7"]
let times2 = collection.sequencedFlatMapEachCompact(on: self.eventLoop) { val -> EventLoopFuture<Int?> in
guard let int = Int(val) else { return self.eventLoop.makeSucceededFuture(nil) }
Expand Down

0 comments on commit 3be4b64

Please sign in to comment.