Skip to content

Commit d0f41df

Browse files
authored
Swift 6: Fix concurrency warnings (#23)
* Fix concurrency warnings * Update json api * Update readme * Build on swift 5.9
1 parent 5f847f2 commit d0f41df

File tree

18 files changed

+94
-115
lines changed

18 files changed

+94
-115
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ on: push
55
jobs:
66
build:
77
runs-on: ubuntu-latest
8-
container: ghcr.io/swiftwasm/swift:5.7
8+
container: ghcr.io/swiftwasm/swift:5.9
99

1010
steps:
11-
- uses: actions/checkout@v3
11+
- uses: actions/checkout@v4
1212

1313
- run: swift --version
1414

15-
- run: swift build -c debug --triple wasm32-unknown-wasi
15+
- run: swift build -c debug --triple wasm32-unknown-wasi

.github/workflows/codeql.yml

Lines changed: 0 additions & 38 deletions
This file was deleted.

Package.resolved

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.6
1+
// swift-tools-version:5.9
22

33
import PackageDescription
44

@@ -17,9 +17,29 @@ let package = Package(
1717
.package(url: "https://github.com/apple/swift-crypto", from: "3.0.0")
1818
],
1919
targets: [
20-
.target(name: "Compute", dependencies: ["ComputeRuntime", .product(name: "Crypto", package: "swift-crypto")]),
21-
.target(name: "ComputeRuntime"),
22-
.executableTarget(name: "ComputeDemo", dependencies: ["Compute"]),
23-
.testTarget(name: "ComputeTests", dependencies: ["Compute"])
20+
.target(
21+
name: "Compute",
22+
dependencies: [
23+
"ComputeRuntime",
24+
.product(name: "Crypto", package: "swift-crypto")
25+
],
26+
swiftSettings: [
27+
.enableExperimentalFeature("StrictConcurrency")
28+
]
29+
),
30+
.target(
31+
name: "ComputeRuntime",
32+
swiftSettings: [
33+
.enableExperimentalFeature("StrictConcurrency")
34+
]
35+
),
36+
.executableTarget(
37+
name: "ComputeDemo",
38+
dependencies: ["Compute"]
39+
),
40+
.testTarget(
41+
name: "ComputeTests",
42+
dependencies: ["Compute"]
43+
)
2444
]
2545
)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ swift package init --type executable
1515
Install the Compute runtime:
1616

1717
```swift
18-
.package(url: "https://github.com/swift-cloud/Compute", from: "2.19.0")
18+
.package(url: "https://github.com/swift-cloud/Compute", from: "3.0.0")
1919
```
2020

2121
Add it as a target dependency:

Sources/Compute/Console.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
public let console = Console()
99

10-
public struct Console {
10+
public struct Console: Sendable {
1111

1212
public var prefix: String? = nil
1313

@@ -25,19 +25,18 @@ public struct Console {
2525
}
2626

2727
public func error(_ items: Any...) {
28+
var errorStream = StandardErrorOutputStream()
2829
let text = items.map { String(describing: $0) }.joined(separator: " ")
2930
if let prefix = prefix {
30-
print(prefix, text, to: &StandardErrorOutputStream.default)
31+
print(prefix, text, to: &errorStream)
3132
} else {
32-
print(text, to: &StandardErrorOutputStream.default)
33+
print(text, to: &errorStream)
3334
}
3435
}
3536
}
3637

3738
fileprivate struct StandardErrorOutputStream: TextOutputStream {
3839

39-
fileprivate static var `default` = StandardErrorOutputStream()
40-
4140
private let stderr = FileHandle.standardError
4241

4342
func write(_ string: String) {

Sources/Compute/Fanout/FanoutMessage.swift

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,16 @@ extension FanoutMessage {
7474
return try decoder.decode(type, from: data())
7575
}
7676

77-
public func json() throws -> Any {
78-
return try JSONSerialization.jsonObject(with: data())
77+
public func json<T: Sendable>() throws -> T {
78+
return try JSONSerialization.jsonObject(with: data()) as! T
7979
}
8080

81-
public func jsonObject() throws -> [String: Any] {
82-
guard let json = try JSONSerialization.jsonObject(with: data()) as? [String: Any] else {
83-
throw FanoutMessageError.invalidFormat
84-
}
85-
return json
81+
public func jsonObject() throws -> [String: Sendable] {
82+
return try json()
8683
}
8784

88-
public func jsonArray() throws -> [Any] {
89-
guard let json = try JSONSerialization.jsonObject(with: data()) as? [Any] else {
90-
throw FanoutMessageError.invalidFormat
91-
}
92-
return json
85+
public func jsonArray() throws -> [Sendable] {
86+
return try json()
9387
}
9488

9589
public func data() throws -> Data {

Sources/Compute/Fastly/FastlyEnvironment.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ extension Fastly {
2929
}
3030

3131
extension Fastly.Environment {
32-
public static var cacheGeneration = current["FASTLY_CACHE_GENERATION"] ?? "local"
32+
public static let cacheGeneration = current["FASTLY_CACHE_GENERATION"] ?? "local"
3333

34-
public static var customerId = current["FASTLY_CUSTOMER_ID"] ?? "local"
34+
public static let customerId = current["FASTLY_CUSTOMER_ID"] ?? "local"
3535

36-
public static var hostname = current["FASTLY_HOSTNAME"] ?? "localhost"
36+
public static let hostname = current["FASTLY_HOSTNAME"] ?? "localhost"
3737

38-
public static var pop = current["FASTLY_POP"] ?? "local"
38+
public static let pop = current["FASTLY_POP"] ?? "local"
3939

40-
public static var region = current["FASTLY_REGION"] ?? "local"
40+
public static let region = current["FASTLY_REGION"] ?? "local"
4141

42-
public static var serviceId = current["FASTLY_SERVICE_ID"] ?? "local"
42+
public static let serviceId = current["FASTLY_SERVICE_ID"] ?? "local"
4343

44-
public static var serviceVersion = current["FASTLY_SERVICE_VERSION"] ?? "0"
44+
public static let serviceVersion = current["FASTLY_SERVICE_VERSION"] ?? "0"
4545

46-
public static var traceId = current["FASTLY_TRACE_ID"] ?? "local"
46+
public static let traceId = current["FASTLY_TRACE_ID"] ?? "local"
4747

4848
public static var viceroy: Bool {
4949
return hostname == "localhost"

Sources/Compute/Fastly/FastlyStubs.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ func fastly_cache__cache_transaction_cancel(_ handle: WasiHandle) -> Int32 { fat
205205
func fastly_device__device_detection_lookup(
206206
_ user_agent: UnsafePointer<CChar>!,
207207
_ user_agent_len: Int,
208-
_ buf: UnsafeMutablePointer<CChar>!,
208+
_ buf: UnsafeMutablePointer<UInt8>!,
209209
_ buf_len: Int,
210210
_ nwritten: UnsafeMutablePointer<Int>!
211211
) -> Int32 { fatalError() }

Sources/Compute/Fetch/Fetch+Wasi.swift

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ internal struct WasiFetcher: Sendable {
8484

8585
// Register the backend
8686
if Fastly.Environment.viceroy, request.backend != "localhost" {
87-
try registerDynamicBackend(request.backend, for: httpRequest, ssl: urlComponents.scheme == "https")
87+
try await dynamicBackends.register(request.backend, for: httpRequest, ssl: urlComponents.scheme == "https")
8888
}
8989

9090
// Issue async request
@@ -119,25 +119,30 @@ internal struct WasiFetcher: Sendable {
119119
}
120120
}
121121
}
122+
}
122123

123-
private static var dynamicBackends: Set<String> = []
124+
extension WasiFetcher {
125+
private static let dynamicBackends = DynamicBackendRepository()
124126

125-
private static func registerDynamicBackend(_ backend: String, for request: Fastly.Request, ssl: Bool) throws {
126-
// Make sure we didn't already register the backend
127-
guard dynamicBackends.contains(backend) == false else {
128-
return
129-
}
127+
private actor DynamicBackendRepository {
130128

131-
// Attempt to register the backend
132-
do {
133-
try request.registerDynamicBackend(name: backend, target: backend, options: .init(ssl: ssl))
134-
} catch WasiStatus.unexpected {
135-
// ignore
136-
} catch {
137-
throw error
138-
}
129+
private var state: Set<String> = []
130+
131+
func register(_ backend: String, for request: Fastly.Request, ssl: Bool) throws {
132+
// Make sure we didn't already register the backend
133+
guard !state.contains(backend) else { return }
139134

140-
// Mark the backend as registered
141-
dynamicBackends.insert(backend)
135+
// Mark the backend as registered
136+
defer { state.insert(backend) }
137+
138+
// Attempt to register the backend
139+
do {
140+
try request.registerDynamicBackend(name: backend, target: backend, options: .init(ssl: ssl))
141+
} catch WasiStatus.unexpected {
142+
// ignore
143+
} catch {
144+
throw error
145+
}
146+
}
142147
}
143148
}

0 commit comments

Comments
 (0)