diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2022-04-05 09:13:46 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2022-04-05 09:13:46 +0200 |
| commit | f758f894da5e368e54c83bd59013074192ce12be (patch) | |
| tree | 172961804441441ac6800d0c463b1e99feec5912 /ios/MullvadVPN/AddressCache | |
| parent | 0f313bf16aae17e43981ad9716d9c73c780ea8db (diff) | |
| parent | 25ed6a8ea14ab9ef2442abb08d4ef2de0a5de8a9 (diff) | |
| download | mullvadvpn-f758f894da5e368e54c83bd59013074192ce12be.tar.xz mullvadvpn-f758f894da5e368e54c83bd59013074192ce12be.zip | |
Merge branch 'result-operation-subclass'
Diffstat (limited to 'ios/MullvadVPN/AddressCache')
| -rw-r--r-- | ios/MullvadVPN/AddressCache/AddressCacheTracker.swift | 26 | ||||
| -rw-r--r-- | ios/MullvadVPN/AddressCache/UpdateAddressCacheOperation.swift | 102 |
2 files changed, 62 insertions, 66 deletions
diff --git a/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift b/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift index 8502d12ffc..de84265b1e 100644 --- a/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift +++ b/ios/MullvadVPN/AddressCache/AddressCacheTracker.swift @@ -83,16 +83,16 @@ extension AddressCache { } } - func updateEndpoints(completionHandler: ((_ result: CacheUpdateResult) -> Void)? = nil) -> Cancellable { + func updateEndpoints(completionHandler: ((_ completion: OperationCompletion<CacheUpdateResult, Error>) -> Void)? = nil) -> Cancellable { let operation = UpdateAddressCacheOperation( queue: stateQueue, restClient: restClient, store: store, updateInterval: Self.updateInterval, - completionHandler: { [weak self] result in - self?.handleCacheUpdateResult(result) + completionHandler: { [weak self] completion in + self?.handleCacheUpdateCompletion(completion) - completionHandler?(result) + completionHandler?(completion) } ) @@ -144,20 +144,22 @@ extension AddressCache { } } - private func handleCacheUpdateResult(_ result: AddressCache.CacheUpdateResult) { - switch result { - case .success: - logger.debug("Finished updating address cache") + private func handleCacheUpdateCompletion(_ completion: OperationCompletion<AddressCache.CacheUpdateResult, Error>) { + switch completion { + case .success(let updateResult): + switch updateResult { + case .finished: + logger.debug("Finished updating address cache") + case .throttled: + logger.debug("Address cache update was throttled") + } + lastFailureAttemptDate = nil case .failure(let error): logger.error(chainedError: AnyChainedError(error), message: "Failed to update address cache") lastFailureAttemptDate = Date() - case .throttled: - logger.debug("Address cache update was throttled") - lastFailureAttemptDate = nil - case .cancelled: logger.debug("Address cache update was cancelled") lastFailureAttemptDate = Date() diff --git a/ios/MullvadVPN/AddressCache/UpdateAddressCacheOperation.swift b/ios/MullvadVPN/AddressCache/UpdateAddressCacheOperation.swift index 8fcd41b7dd..81940acd21 100644 --- a/ios/MullvadVPN/AddressCache/UpdateAddressCacheOperation.swift +++ b/ios/MullvadVPN/AddressCache/UpdateAddressCacheOperation.swift @@ -11,63 +11,48 @@ import Foundation extension AddressCache { enum CacheUpdateResult { - /// Operation was cancelled. - case cancelled - /// Address cache update was throttled as it was requested too early. case throttled(_ lastUpdateDate: Date) - /// Failure to update address cache. - case failure(Error) - /// Address cache is successfully updated. - case success - - var isTaskCompleted: Bool { - switch self { - case .cancelled, .failure: - return false - case .success, .throttled: - return true - } - } + case finished } - class UpdateAddressCacheOperation: AsyncOperation { - typealias CompletionHandler = (_ result: CacheUpdateResult) -> Void - + class UpdateAddressCacheOperation: ResultOperation<CacheUpdateResult, Error> { private let queue: DispatchQueue private let restClient: REST.Client private let store: AddressCache.Store private let updateInterval: TimeInterval - private var completionHandler: CompletionHandler? - private var restCancellationHandle: Cancellable? + private var requestTask: Cancellable? init(queue: DispatchQueue, restClient: REST.Client, store: AddressCache.Store, updateInterval: TimeInterval, completionHandler: CompletionHandler?) { self.queue = queue self.restClient = restClient self.store = store self.updateInterval = updateInterval - self.completionHandler = completionHandler + + super.init(completionQueue: queue, completionHandler: completionHandler) } - override func cancel() { + override func main() { queue.async { - super.cancel() - self.restCancellationHandle?.cancel() + self.startUpdate() } } - override func main() { + override func cancel() { + super.cancel() + queue.async { - self.startUpdate() + self.requestTask?.cancel() + self.requestTask = nil } } private func startUpdate() { guard !isCancelled else { - completeOperation(with: .cancelled) + finish(completion: .cancelled) return } @@ -75,40 +60,49 @@ extension AddressCache { let nextUpdate = Date(timeInterval: updateInterval, since: lastUpdate) guard nextUpdate <= Date() else { - completeOperation(with: .throttled(lastUpdate)) + finish(completion: .success(.throttled(lastUpdate))) return } - restCancellationHandle = restClient.getAddressList(retryStrategy: .default) { restResult in - self.queue.async { - switch restResult { - case .success(let newEndpoints): - self.store.setEndpoints(newEndpoints) { error in - self.queue.async { - if let error = error { - self.completeOperation(with: .failure(error)) - } else { - self.completeOperation(with: .success) - } - } - } + requestTask = restClient.getAddressList(retryStrategy: .default) { completion in + self.queue.async { + self.handleResponse(completion) + } + } + } - case .failure(let error): - if case URLError.cancelled = error { - self.completeOperation(with: .cancelled) - } else { - self.completeOperation(with: .failure(error)) - } - } + private func handleResponse(_ completion: OperationCompletion<[AnyIPEndpoint], REST.Error>) { + switch completion { + case .success(let newEndpoints): + self.store.setEndpoints(newEndpoints) { error in + if let error = error { + self.finish(completion: .failure(error)) + } else { + self.finish(completion: .success(.finished)) } } - } - private func completeOperation(with result: CacheUpdateResult) { - completionHandler?(result) - completionHandler = nil + case .failure(let error): + if case URLError.cancelled = error { + self.finish(completion: .cancelled) + } else { + self.finish(completion: .failure(error)) + } + + case .cancelled: + self.finish(completion: .cancelled) + } + } + } +} - finish() +extension OperationCompletion where Success == AddressCache.CacheUpdateResult { + var isTaskCompleted: Bool { + switch self { + case .success: + return true + case .cancelled, .failure: + return false } } } |
