Преглед изворни кода

Release loop actor before publishing isLooping(false)

In finalizeLoop, the actor was freed after isLooping.send(false). That
opened a window where subscribers (Home UI, deviceDataManager.
loopInProgress) saw the loop as finished while the actor was still
held. A heartbeat arriving in that window would call loop(), which
would then await tryStart, get false back, and log "Loop skipped
(already running or too soon)" at the tail of every successful loop.

Swap the order: free the actor first, then publish state.
Marvin Polscheit пре 1 дан
родитељ
комит
77f10c1df0
1 измењених фајлова са 5 додато и 1 уклоњено
  1. 5 1
      Trio/Sources/APS/APSManager.swift

+ 5 - 1
Trio/Sources/APS/APSManager.swift

@@ -380,8 +380,12 @@ final class BaseAPSManager: APSManager, Injectable {
 
     /// Single exit point for loop — replaces the old `loopCompleted()`.
     private func finalizeLoop(error: Error? = nil, loopStatRecord: LoopStats) async {
-        isLooping.send(false)
+        // Free the actor first, then publish state. If we published first, a heartbeat
+        // arriving in the gap would see the loop as done, call loop(), and trip
+        // tryStart on the still-busy actor — producing a spurious "Loop skipped" log
+        // at the tail of every loop. No functional harm, but unnecessary noise.
         await loopGuard.finish()
+        isLooping.send(false)
 
         if let error = error {
             warning(.apsManager, "Loop failed with error: \(error)")