Просмотр исходного кода

Prevent stale forecast runs from overwriting fresher results

Marvin Polscheit 3 дней назад
Родитель
Сommit
6b8b59a1f8

+ 3 - 2
Trio/Sources/Modules/Home/HomeStateModel+Setup/DeterminationSetup.swift

@@ -14,8 +14,9 @@ extension Home.StateModel {
         do {
             try enactedDeterminationController.performFetch()
             updateEnactedDeterminationFromController()
-            // Initial population runs immediately — no burst to coalesce at startup.
-            Task { @MainActor in
+            // Initial population; assigned to `forecastUpdateTask` so a change arriving
+            // during startup cancels it instead of racing it.
+            forecastUpdateTask = Task { @MainActor in
                 await self.updateForecastData()
             }
         } catch {

+ 7 - 0
Trio/Sources/Modules/Home/HomeStateModel+Setup/ForecastSetup.swift

@@ -33,9 +33,14 @@ extension Home.StateModel {
     }
 
     // Update forecast data and UI on the main thread
+    //
+    // Runs inside `forecastUpdateTask`; cancellation is checked after every suspension
+    // point so a superseded run cannot overwrite fresher results.
     @MainActor func updateForecastData() async {
         let forecastDataIDs = await preprocessForecastData()
 
+        guard !Task.isCancelled else { return }
+
         var allForecastValues = [[Int]]()
         var preprocessedData = [(id: UUID, forecast: Forecast, forecastValue: ForecastValue)]()
 
@@ -97,6 +102,8 @@ extension Home.StateModel {
             return (minForecast, maxForecast)
         }.value
 
+        guard !Task.isCancelled else { return }
+
         minForecast = minResult
         maxForecast = maxResult
     }