taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit 696dfc84922362363a75859aeb6b3bf3c8366dc3
parent f7e9c2e0b2775b64daa26b2d6d9693031caf3d0f
Author: Marc Stibane <marc@taler.net>
Date:   Fri, 13 Oct 2023 10:05:29 +0200

AsyncSemaphore to serialize Getbalances

Diffstat:
MTalerWallet1/Model/Model+Balances.swift | 21++++++++++++++-------
MTalerWallet1/Model/WalletModel.swift | 3++-
2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/TalerWallet1/Model/Model+Balances.swift b/TalerWallet1/Model/Model+Balances.swift @@ -45,13 +45,20 @@ extension WalletModel { /// fetch Balances from Wallet-Core. No networking involved @MainActor func balancesM(_ stack: CallStack) async -> [Balance] { // M for MainActor - do { - let request = Balances() - let response = try await sendRequest(request, ASYNCDELAY) - return response.balances // trigger view update in BalancesListView - } catch { - logger.error("balancesM failed: \(error)") - return [] + await semaphore.wait() + defer { semaphore.signal() } + if cachedBalances == nil { + do { + let request = Balances() + let response = try await sendRequest(request, ASYNCDELAY) + cachedBalances = response.balances + } catch { + logger.error("balancesM failed: \(error)") + // TODO: show error + } + } else { + logger.trace("returning cached Balances") } + return cachedBalances ?? [] } } diff --git a/TalerWallet1/Model/WalletModel.swift b/TalerWallet1/Model/WalletModel.swift @@ -9,13 +9,14 @@ import os.log fileprivate let DATABASE = "talerwalletdb-v30" fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for debugging - // MARK: - /// The "virtual" base class for all models class WalletModel: ObservableObject { public static let shared = WalletModel() static func className() -> String {"\(self)"} let logger = Logger (subsystem: "net.taler.gnu", category: "WalletModel") + let semaphore = AsyncSemaphore(value: 1) + var cachedBalances: [Balance]? = nil func sendRequest<T: WalletBackendFormattedRequest> (_ request: T, _ delay: UInt = 0) async throws -> T.Response { // T for any Thread