Skip to content

Commit 2bfb7c1

Browse files
committed
Add async to Websocket internal completion handlers
1 parent cacdd36 commit 2bfb7c1

File tree

3 files changed

+59
-48
lines changed

3 files changed

+59
-48
lines changed

apollo-ios/Sources/ApolloWebSocket/OperationMessage.swift

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,24 @@ final class OperationMessage {
5757
self.serialized = serialized
5858
}
5959

60-
func parse(handler: (ParseHandler) -> Void) {
60+
func parse(handler: (ParseHandler) async -> Void) async {
6161
guard let serialized = self.serialized else {
62-
handler(ParseHandler(nil,
63-
nil,
64-
nil,
65-
WebSocketError(payload: nil,
66-
error: nil,
67-
kind: .serializedMessageError)))
62+
await handler(ParseHandler(nil,
63+
nil,
64+
nil,
65+
WebSocketError(payload: nil,
66+
error: nil,
67+
kind: .serializedMessageError)))
6868
return
6969
}
7070

7171
guard let data = self.serialized?.data(using: (.utf8) ) else {
72-
handler(ParseHandler(nil,
73-
nil,
74-
nil,
75-
WebSocketError(payload: nil,
76-
error: nil,
77-
kind: .unprocessedMessage(serialized))))
72+
await handler(ParseHandler(nil,
73+
nil,
74+
nil,
75+
WebSocketError(payload: nil,
76+
error: nil,
77+
kind: .unprocessedMessage(serialized))))
7878
return
7979
}
8080

@@ -89,18 +89,18 @@ final class OperationMessage {
8989
type = json["type"] as? String
9090
payload = json["payload"] as? JSONObject
9191

92-
handler(ParseHandler(type,
93-
id,
94-
payload,
95-
nil))
92+
await handler(ParseHandler(type,
93+
id,
94+
payload,
95+
nil))
9696
}
9797
catch {
98-
handler(ParseHandler(type,
99-
id,
100-
payload,
101-
WebSocketError(payload: payload,
102-
error: error,
103-
kind: .unprocessedMessage(serialized))))
98+
await handler(ParseHandler(type,
99+
id,
100+
payload,
101+
WebSocketError(payload: payload,
102+
error: error,
103+
kind: .unprocessedMessage(serialized))))
104104
}
105105
}
106106
}

apollo-ios/Sources/ApolloWebSocket/WebSocketTask.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ final class WebSocketTask<Operation: GraphQLOperation>: Sendable, Cancellable {
1616
/// - Parameter completionHandler: A completion handler to fire when the operation has a result.
1717
init(_ ws: WebSocketTransport,
1818
_ operation: Operation,
19-
_ completionHandler: @escaping @Sendable (_ result: Result<JSONObject, any Error>) -> Void) {
19+
_ completionHandler: @escaping @Sendable (_ result: Result<JSONObject, any Error>) async -> Void) {
2020
sequenceNumber = ws.sendHelper(operation: operation, resultHandler: completionHandler)
2121
transport = ws
2222
}

apollo-ios/Sources/ApolloWebSocket/WebSocketTransport.swift

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public class WebSocketTransport: @unchecked Sendable {
5050
private var queue: [Int: String] = [:]
5151

5252
@Atomic
53-
private var subscribers = [String: (Result<JSONObject, any Error>) -> Void]()
53+
private var subscribers = [String: (Result<JSONObject, any Error>) async -> Void]()
5454
@Atomic
5555
private var subscriptions : [String: String] = [:]
5656
let processingQueue = DispatchQueue(label: "com.apollographql.WebSocketTransport")
@@ -187,8 +187,8 @@ public class WebSocketTransport: @unchecked Sendable {
187187
return websocket.write(ping: data, completion: completionHandler)
188188
}
189189

190-
private func processMessage(text: String) {
191-
OperationMessage(serialized: text).parse { parseHandler in
190+
private func processMessage(text: String) async {
191+
await OperationMessage(serialized: text).parse { parseHandler in
192192
guard
193193
let type = parseHandler.type,
194194
let messageType = OperationMessage.Types(rawValue: type) else {
@@ -215,14 +215,14 @@ public class WebSocketTransport: @unchecked Sendable {
215215
// subscriber probably unsubscribed.
216216
if let responseHandler = subscribers[id] {
217217
if let payload = parseHandler.payload {
218-
responseHandler(.success(payload))
218+
await responseHandler(.success(payload))
219219
} else if let error = parseHandler.error {
220-
responseHandler(.failure(error))
220+
await responseHandler(.failure(error))
221221
} else {
222222
let websocketError = WebSocketError(payload: parseHandler.payload,
223223
error: parseHandler.error,
224224
kind: .neitherErrorNorPayloadReceived)
225-
responseHandler(.failure(websocketError))
225+
await responseHandler(.failure(websocketError))
226226
}
227227
}
228228
case .complete:
@@ -266,8 +266,10 @@ public class WebSocketTransport: @unchecked Sendable {
266266
}
267267

268268
private func notifyErrorAllHandlers(_ error: any Error) {
269-
for (_, handler) in subscribers {
270-
handler(.failure(error))
269+
Task {
270+
for (_, handler) in subscribers {
271+
await handler(.failure(error))
272+
}
271273
}
272274
}
273275

@@ -335,10 +337,13 @@ public class WebSocketTransport: @unchecked Sendable {
335337
self.websocket.delegate = nil
336338
}
337339

338-
func sendHelper<Operation: GraphQLOperation>(operation: Operation, resultHandler: @escaping @Sendable (_ result: Result<JSONObject, any Error>) -> Void) -> String? {
339-
let body = config.requestBodyCreator.requestBody(for: operation,
340-
sendQueryDocument: true,
341-
autoPersistQuery: false)
340+
func sendHelper<Operation: GraphQLOperation>(operation: Operation, resultHandler: @escaping @Sendable (_ result: Result<JSONObject, any Error>) async -> Void) -> String? {
341+
let body = config.requestBodyCreator.requestBody(
342+
for: operation,
343+
sendQueryDocument: true,
344+
autoPersistQuery: false,
345+
clientAwarenessMetadata: config.clientAwarenessMetadata
346+
)
342347
let identifier = config.operationMessageIdCreator.requestId()
343348

344349
let messageType: OperationMessage.Types
@@ -460,36 +465,40 @@ extension WebSocketTransport: NetworkTransport {
460465

461466
#warning("TODO: stream never finishes. WebSocketTask does not report subscription termination.")
462467
return AsyncThrowingStream { continuation in
463-
let task = WebSocketTask(self, operation) { [weak store, contextIdentifier] result in
464-
Task {
468+
let wsTask = WebSocketTask(self, operation) { [weak store, contextIdentifier] result in
469+
do {
465470
try Task.checkCancellation()
466-
471+
467472
let jsonBody = try result.get()
468473
let response = GraphQLResponse(operation: operation, body: jsonBody)
469-
474+
470475
if let store = store {
471476
let (graphQLResult, parsedRecords) = try await response.parseResult()
472-
477+
473478
try Task.checkCancellation()
474-
479+
475480
guard let records = parsedRecords else {
476481
continuation.yield(graphQLResult)
477482
return
478483
}
479-
484+
480485
try await store.publish(records: records, identifier: contextIdentifier)
481486
continuation.yield(graphQLResult)
482-
487+
483488
} else {
484489
let graphQLResult = try await response.parseResultFast()
485490
try Task.checkCancellation()
486-
491+
487492
continuation.yield(graphQLResult)
488493
}
494+
} catch {
495+
continuation.finish(throwing: error)
489496
}
490-
}
497+
}
491498

492-
continuation.onTermination = { _ in task.cancel() }
499+
continuation.onTermination = {
500+
_ in wsTask.cancel()
501+
}
493502
}
494503
}
495504
}
@@ -592,7 +601,9 @@ extension WebSocketTransport: WebSocketClientDelegate {
592601
}
593602

594603
public func websocketDidReceiveMessage(socket: any WebSocketClient, text: String) {
595-
self.processMessage(text: text)
604+
Task {
605+
await self.processMessage(text: text)
606+
}
596607
}
597608

598609
public func websocketDidReceiveData(socket: any WebSocketClient, data: Data) {

0 commit comments

Comments
 (0)