Skip to content

Commit

Permalink
fix: Thread safe subscription watcher cancel
Browse files Browse the repository at this point in the history
  • Loading branch information
lawmicha committed Feb 28, 2022
1 parent b3acd23 commit aa93d39
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions AWSAppSyncClient/AWSAppSyncSubscriptionWatcher.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public final class AWSAppSyncSubscriptionWatcher<Subscription: GraphQLSubscripti
private var subscriptionItem: SubscriptionItem?

private let handlerQueue: DispatchQueue
private let subscriptionsQueue: DispatchQueue
private var resultHandler: SubscriptionResultHandler<Subscription>?
private var connectedCallback: (() -> Void)?
private var statusChangeHandler: SubscriptionStatusChangeHandler?
Expand Down Expand Up @@ -57,6 +58,7 @@ public final class AWSAppSyncSubscriptionWatcher<Subscription: GraphQLSubscripti
resultHandler(result, transaction, error)
}
}
self.subscriptionsQueue = subscriptionsQueue
subscriptionsQueue.async { [weak self] in
guard let self = self else {return}
if !self.isCancelled {
Expand Down Expand Up @@ -177,22 +179,26 @@ public final class AWSAppSyncSubscriptionWatcher<Subscription: GraphQLSubscripti
/// Specifically, this means that cancelling a subscription watcher will not invoke `statusChangeHandler` or
/// `resultHandler`, although it will set the internal state of the watcher to `.disconnected`
public func cancel() {
if self.cancellationSource == .none {
self.cancellationSource = .user
if !self.isCancelled {
if self.cancellationSource == .none {
self.cancellationSource = .user
}
self.performCleanUpTasksOnCancel()
}
performCleanUpTasksOnCancel()
}

internal func performCleanUpTasksOnCancel() {
isCancelled = true
status = .disconnected
resultHandler = nil
statusChangeHandler = nil

if self.cancellationSource != .error, let item = subscriptionItem {
connection?.unsubscribe(item: item)
subscriptionsQueue.async { [weak self] in
guard let self = self else {return}
if self.cancellationSource != .error, let item = self.subscriptionItem {
self.connection?.unsubscribe(item: item)
}
self.connection = nil
}
connection = nil
}

}

0 comments on commit aa93d39

Please sign in to comment.