-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add swift concurrency (async/await) support for async intercept…
…ors (#85) Co-authored-by: Ian Saultz <52051793+atierian@users.noreply.github.com>
- Loading branch information
Showing
31 changed files
with
1,503 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
...ealtimeConnectionAsync/RealtimeConnectionProviderAsync+ConnectionInterceptableAsync.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#if swift(>=5.5.2) | ||
|
||
import Foundation | ||
|
||
@available(iOS 13.0.0, *) | ||
extension RealtimeConnectionProviderAsync: ConnectionInterceptableAsync { | ||
|
||
public func addInterceptor(_ interceptor: ConnectionInterceptorAsync) { | ||
connectionInterceptors.append(interceptor) | ||
} | ||
|
||
public func interceptConnection( | ||
_ request: AppSyncConnectionRequest, | ||
for endpoint: URL | ||
) async -> AppSyncConnectionRequest { | ||
var finalRequest = request | ||
for interceptor in connectionInterceptors { | ||
finalRequest = await interceptor.interceptConnection(finalRequest, for: endpoint) | ||
} | ||
|
||
return finalRequest | ||
} | ||
} | ||
|
||
#endif |
28 changes: 28 additions & 0 deletions
28
...ncRealtimeConnectionAsync/RealtimeConnectionProviderAsync+MessageInterceptableAsync.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#if swift(>=5.5.2) | ||
|
||
import Foundation | ||
|
||
@available(iOS 13.0.0, *) | ||
extension RealtimeConnectionProviderAsync: MessageInterceptableAsync { | ||
public func addInterceptor(_ interceptor: MessageInterceptorAsync) { | ||
messageInterceptors.append(interceptor) | ||
} | ||
|
||
public func interceptMessage(_ message: AppSyncMessage, for endpoint: URL) async -> AppSyncMessage { | ||
var finalMessage = message | ||
for interceptor in messageInterceptors { | ||
finalMessage = await interceptor.interceptMessage(finalMessage, for: endpoint) | ||
} | ||
|
||
return finalMessage | ||
} | ||
} | ||
|
||
#endif |
77 changes: 77 additions & 0 deletions
77
...ider/AppsyncRealtimeConnectionAsync/RealtimeConnectionProviderAsync+StaleConnection.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// | ||
// Copyright Amazon.com Inc. or its affiliates. | ||
// All Rights Reserved. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
#if swift(>=5.5.2) | ||
|
||
import Foundation | ||
|
||
/// Consolidates usage and parameters passed to the `staleConnectionTimer` methods. | ||
@available(iOS 13.0, *) | ||
extension RealtimeConnectionProviderAsync { | ||
|
||
/// Start a stale connection timer, first invalidating and destroying any existing timer | ||
func startStaleConnectionTimer() { | ||
AppSyncLogger.debug( | ||
"[RealtimeConnectionProvider] Starting stale connection timer for \(staleConnectionTimer.interval)s" | ||
) | ||
|
||
staleConnectionTimer.start(interval: RealtimeConnectionProviderAsync.staleConnectionTimeout) { | ||
self.disconnectStaleConnection() | ||
} | ||
} | ||
|
||
/// Reset the stale connection timer in response to receiving a message from the websocket | ||
func resetStaleConnectionTimer(interval: TimeInterval? = nil) { | ||
AppSyncLogger.verbose("[RealtimeConnectionProvider] Resetting stale connection timer") | ||
staleConnectionTimer.reset(interval: interval) | ||
} | ||
|
||
/// Stops the timer when disconnecting the websocket. | ||
func invalidateStaleConnectionTimer() { | ||
staleConnectionTimer.invalidate() | ||
} | ||
|
||
/// Handle updates from the ConnectivityMonitor | ||
func handleConnectivityUpdates(connectivity: ConnectivityPath) { | ||
taskQueue.async { [weak self] in | ||
guard let self = self else { | ||
return | ||
} | ||
AppSyncLogger.debug( | ||
"[RealtimeConnectionProvider] Status: \(self.status). Connectivity status: \(connectivity.status)" | ||
) | ||
if self.status == .connected && connectivity.status == .unsatisfied && !self.isStaleConnection { | ||
AppSyncLogger.debug( | ||
"[RealtimeConnectionProvider] Connetion is stale. Pending reconnect on connectivity." | ||
) | ||
self.isStaleConnection = true | ||
|
||
} else if self.status == .connected && self.isStaleConnection && connectivity.status == .satisfied { | ||
AppSyncLogger.debug( | ||
"[RealtimeConnectionProvider] Connetion is stale. Disconnecting to begin reconnect." | ||
) | ||
self.staleConnectionTimer.invalidate() | ||
self.disconnectStaleConnection() | ||
} | ||
} | ||
} | ||
|
||
/// Fired when the stale connection timer expires | ||
private func disconnectStaleConnection() { | ||
taskQueue.async { [weak self] in | ||
guard let self = self else { | ||
return | ||
} | ||
AppSyncLogger.error("[RealtimeConnectionProvider] Realtime connection is stale, disconnecting.") | ||
self.status = .notConnected | ||
self.isStaleConnection = false | ||
self.websocket.disconnect() | ||
self.updateCallback(event: .error(ConnectionProviderError.connection)) | ||
} | ||
} | ||
} | ||
#endif |
Oops, something went wrong.