Skip to content

Commit 3e845c2

Browse files
committed
Fix: Properly keep the cancellables
DVDRental was stuck in connecting. This was because the Combine streams were not held onto. Originally I thought the streams could "self retain", but that doesn't fly anymore. So added tokens for - count query - range query - model fetch And DVDRental seems to be back in a working state.
1 parent 4faf1cf commit 3e845c2

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

Sources/DirectToSwiftUI/ViewModel/D2SDisplayGroup.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ public final class D2SDisplayGroup<Object: OActiveRecord>
120120

121121
private func integrateCount(_ count: Int) {
122122
assert(_dispatchPreconditionTest(.onQueue(.main)))
123-
123+
self.countFetchToken = nil
124+
124125
#if false // nope, a fetch count means we rebuild!
125126
if count == results.count { return } // all good already
126127
#endif
@@ -138,11 +139,14 @@ public final class D2SDisplayGroup<Object: OActiveRecord>
138139
results.clearOrderAndApplyNewCount(count)
139140
}
140141

142+
private var countFetchToken : AnyCancellable?
143+
141144
private func fetchCount(_ fetchSpecification: FetchSpecification) {
142145
let fs = fetchSpecification // has to be done, can't use inside fetchCount?
143-
_ = dataSource.fetchCount(fs, on: D2SFetchQueue)
146+
countFetchToken = dataSource.fetchCount(fs, on: D2SFetchQueue)
144147
.receive(on: RunLoop.main)
145148
.catch { ( error : Swift.Error ) -> Just<Int> in
149+
self.countFetchToken = nil
146150
self.handleError(error)
147151
return Just(0)
148152
}
@@ -196,8 +200,13 @@ public final class D2SDisplayGroup<Object: OActiveRecord>
196200
self.results = newResults
197201
}
198202

199-
private struct Query: Equatable {
203+
private final class Query: Equatable {
200204
let range : Range<Int>
205+
var token : AnyCancellable?
206+
init(range: Range<Int>) { self.range = range }
207+
static func ==(lhs: Query, rhs: Query) -> Bool {
208+
return lhs.range == rhs.range
209+
}
201210
}
202211
private var activeQueries = [ Query ]()
203212

@@ -242,7 +251,7 @@ public final class D2SDisplayGroup<Object: OActiveRecord>
242251
let query = Query(range: fetchRange)
243252
activeQueries.append(query) // keep it alive
244253

245-
_ = dataSource.fetchGlobalIDs(fs, on: D2SFetchQueue)
254+
query.token = dataSource.fetchGlobalIDs(fs, on: D2SFetchQueue)
246255
.receive(on: RunLoop.main)
247256
.flatMap { ( globalIDs ) -> AnyPublisher<[ Object ], Error> in
248257
var missingGIDs = Set<GlobalID>()

Sources/DirectToSwiftUI/ViewModel/D2SRuleEnvironment.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,21 @@ public final class D2SRuleEnvironment: ObservableObject {
4343
ruleContext[D2SKeys.model] = model
4444
}
4545

46+
private var modelFetch : AnyCancellable?
47+
4648
public func resume() {
4749
guard databaseModel == nil else { return }
4850

4951
// TODO: setup timer to refetch and compare model tag
50-
_ = adaptor.fetchModel(on: D2SFetchQueue)
52+
modelFetch = adaptor.fetchModel(on: D2SFetchQueue)
5153
.map { ( model, tag ) in
5254
FancyModelMaker(model: model).fancyfyModel()
5355
}
5456
.receive(on: RunLoop.main)
5557
.catch { ( error : Swift.Error ) -> Just<Model> in
5658
self.error = error
5759
globalD2SLogger.error("failed to fetch model:", error)
60+
self.modelFetch = nil
5861
return Just(Model(entities: [
5962
ModelEntity(name: "Could not load model.")
6063
]))
@@ -64,6 +67,7 @@ public final class D2SRuleEnvironment: ObservableObject {
6467
self.adaptor.model = model
6568
}
6669
self.setupWithModel(model)
70+
self.modelFetch = nil
6771
}
6872
}
6973
}

0 commit comments

Comments
 (0)