Skip to content

Commit

Permalink
Merge pull request #21 from ZirgVoice/concurrency
Browse files Browse the repository at this point in the history
Concurrency
  • Loading branch information
NeedleInAJayStack authored Oct 26, 2024
2 parents c6129d9 + 0af209a commit 52b1f3d
Show file tree
Hide file tree
Showing 11 changed files with 1,218 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
runs-on: ubuntu-22.04
strategy:
matrix:
swift: ["5.7", "5.8", "5.9", "5.10"]
swift: ["5.9", "5.10"]
steps:
- uses: swift-actions/setup-swift@v2
with:
Expand Down
78 changes: 65 additions & 13 deletions Package.resolved
Original file line number Diff line number Diff line change
@@ -1,16 +1,68 @@
{
"object": {
"pins": [
{
"package": "swift-nio",
"repositoryURL": "https://github.com/apple/swift-nio.git",
"state": {
"branch": null,
"revision": "51c3fc2e4a0fcdf4a25089b288dd65b73df1b0ef",
"version": "2.37.0"
}
"pins" : [
{
"identity" : "async-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/adam-fowler/async-collections",
"state" : {
"revision" : "726af96095a19df6b8053ddbaed0a727aa70ccb2",
"version" : "0.1.0"
}
]
},
"version": 1
},
{
"identity" : "swift-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-algorithms.git",
"state" : {
"revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42",
"version" : "1.2.0"
}
},
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "671108c96644956dddcd89dd59c203dcdb36cec7",
"version" : "1.1.4"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "f7dc3f527576c398709b017584392fb58592e7f5",
"version" : "2.75.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
"version" : "1.0.2"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "c8a44d836fe7913603e246acab7c528c2e780168",
"version" : "1.4.0"
}
}
],
"version" : 2
}
25 changes: 21 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,19 +1,36 @@
// swift-tools-version:5.0
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "DataLoader",
platforms: [.macOS(.v12), .iOS(.v15), .tvOS(.v15), .watchOS(.v8)],
products: [
.library(name: "DataLoader", targets: ["DataLoader"]),
.library(name: "AsyncDataLoader", targets: ["AsyncDataLoader"]),
],
dependencies: [
.package(url: "https://github.com/apple/swift-algorithms.git", from: "1.0.0"),
.package(url: "https://github.com/adam-fowler/async-collections", from: "0.0.1"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0"),
],
targets: [
.target(name: "DataLoader", dependencies: ["NIO", "NIOConcurrencyHelpers"]),
.target(
name: "DataLoader",
dependencies: [
.product(name: "NIO", package: "swift-nio"),
.product(name: "NIOConcurrencyHelpers", package: "swift-nio"),
]
),
.target(
name: "AsyncDataLoader",
dependencies: [
.product(name: "Algorithms", package: "swift-algorithms"),
.product(name: "AsyncCollections", package: "async-collections"),
]
),
.testTarget(name: "DataLoaderTests", dependencies: ["DataLoader"]),
],
swiftLanguageVersions: [.v5]
.testTarget(name: "AsyncDataLoaderTests", dependencies: ["AsyncDataLoader"]),
]
)
55 changes: 55 additions & 0 deletions Sources/AsyncDataLoader/Channel/Channel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
actor Channel<Success: Sendable, Failure: Error>: Sendable {
private var state = State<Success, Failure>()
}

extension Channel {
@discardableResult
func fulfill(_ value: Success) async -> Bool {
if await state.result == nil {
await state.setResult(result: value)

for waiters in await state.waiters {
waiters.resume(returning: value)
}

await state.removeAllWaiters()

return false
}

return true
}

@discardableResult
func fail(_ failure: Failure) async -> Bool {
if await state.failure == nil {
await state.setFailure(failure: failure)

for waiters in await state.waiters {
waiters.resume(throwing: failure)
}

await state.removeAllWaiters()

return false
}

return true
}

var value: Success {
get async throws {
try await withCheckedThrowingContinuation { continuation in
Task {
if let result = await state.result {
continuation.resume(returning: result)
} else if let failure = await self.state.failure {
continuation.resume(throwing: failure)
} else {
await state.appendWaiters(waiters: continuation)
}
}
}
}
}
}
25 changes: 25 additions & 0 deletions Sources/AsyncDataLoader/Channel/State.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
typealias Waiter<Success, Failure> = CheckedContinuation<Success, Error>

actor State<Success, Failure> {
var waiters = [Waiter<Success, Failure>]()
var result: Success?
var failure: Failure?
}

extension State {
func setResult(result: Success) {
self.result = result
}

func setFailure(failure: Failure) {
self.failure = failure
}

func appendWaiters(waiters: Waiter<Success, Failure>...) {
self.waiters.append(contentsOf: waiters)
}

func removeAllWaiters() {
waiters.removeAll()
}
}
Loading

0 comments on commit 52b1f3d

Please sign in to comment.