Skip to content

Commit 780f10c

Browse files
committed
Merge branch 'master' into fix/keychain-access
2 parents d3f8f88 + 2ff4b55 commit 780f10c

File tree

3 files changed

+58
-26
lines changed

3 files changed

+58
-26
lines changed

Bitkit/Services/BackupService.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ class BackupService {
180180
}
181181

182182
VssStoreIdProvider.shared.clearCache()
183-
VssBackupClient.shared.reset()
183+
await VssBackupClient.shared.reset()
184184

185185
Logger.debug("Full restore starting", context: "BackupService")
186186

@@ -504,8 +504,6 @@ class BackupService {
504504

505505
func getLatestBackupTime() async -> UInt64? {
506506
do {
507-
try await vssBackupClient.setup()
508-
509507
let timestamps = await withTaskGroup(of: UInt64?.self) { group in
510508
for category in BackupCategory.allCases where category != .lightningConnections {
511509
group.addTask {

Bitkit/Services/VssBackupClient.swift

Lines changed: 56 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,69 @@
11
import Foundation
22
import VssRustClientFfi
33

4+
/// Actor to coordinate VSS client setup (ensures only one setup runs at a time)
5+
private actor VssSetupCoordinator {
6+
private enum SetupState {
7+
case idle
8+
case inProgress(Task<Void, Error>)
9+
case completed
10+
}
11+
12+
private var state: SetupState = .idle
13+
14+
func awaitSetup(setupAction: @escaping () async throws -> Void) async throws {
15+
switch state {
16+
case .completed:
17+
Logger.debug("VssSetupCoordinator: already completed, returning", context: "VssBackupClient")
18+
return
19+
20+
case let .inProgress(existingTask):
21+
Logger.debug("VssSetupCoordinator: setup in progress, waiting for existing task", context: "VssBackupClient")
22+
try await existingTask.value
23+
Logger.debug("VssSetupCoordinator: existing task completed", context: "VssBackupClient")
24+
return
25+
26+
case .idle:
27+
Logger.debug("VssSetupCoordinator: idle, starting new setup", context: "VssBackupClient")
28+
let task = Task {
29+
try await setupAction()
30+
}
31+
state = .inProgress(task)
32+
33+
do {
34+
try await task.value
35+
state = .completed
36+
Logger.debug("VssSetupCoordinator: setup completed successfully", context: "VssBackupClient")
37+
} catch {
38+
// Reset on any error to allow retry attempts
39+
state = .idle
40+
Logger.debug("VssSetupCoordinator: setup failed, resetting to idle", context: "VssBackupClient")
41+
throw error
42+
}
43+
}
44+
}
45+
46+
func reset() {
47+
Logger.debug("VssSetupCoordinator: reset called", context: "VssBackupClient")
48+
if case let .inProgress(task) = state {
49+
task.cancel()
50+
}
51+
state = .idle
52+
}
53+
}
54+
455
class VssBackupClient {
556
static let shared = VssBackupClient()
657

7-
private var isSetup: Task<Void, Error>?
58+
private let setupCoordinator = VssSetupCoordinator()
859

960
private init() {}
1061

11-
func reset() {
12-
isSetup = nil
62+
func reset() async {
63+
await setupCoordinator.reset()
1364
}
1465

15-
func setup(walletIndex: Int = 0) async throws {
66+
private func setup(walletIndex: Int = 0) async throws {
1667
do {
1768
try await withTimeout(seconds: 30) {
1869
Logger.debug("VSS client setting up…", context: "VssBackupClient")
@@ -87,26 +138,9 @@ class VssBackupClient {
87138
}
88139

89140
private func awaitSetup() async throws {
90-
if let existingSetup = isSetup {
91-
do {
92-
try await existingSetup.value
93-
} catch let error as CancellationError {
94-
isSetup = nil
95-
throw error
96-
}
97-
}
98-
99-
let setupTask = Task {
141+
try await setupCoordinator.awaitSetup { [self] in
100142
try await setup()
101143
}
102-
isSetup = setupTask
103-
104-
do {
105-
try await setupTask.value
106-
} catch let error as CancellationError {
107-
isSetup = nil
108-
throw error
109-
}
110144
}
111145

112146
private func withTimeout<T>(seconds: TimeInterval, operation: @escaping () async throws -> T) async throws -> T {

Bitkit/Utilities/AppReset.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ enum AppReset {
1717

1818
// Stop backup observers and reset VSS client
1919
await BackupService.shared.stopObservingBackups()
20-
VssBackupClient.shared.reset()
20+
await VssBackupClient.shared.reset()
2121

2222
// Stop node and wipe LDK persistence via the wallet API.
2323
try await wallet.wipe()

0 commit comments

Comments
 (0)