فهرست منبع

Broadcast Hash Deduplication Fix

The hash was being marked as "sent" BEFORE the actual send completed, as getAppStatus callback never fires or is severely delayed
All future broadcasts with same/similar data were blocked :
The hash from 21:40:07 is still stored in lastSentDataHash
Even though it was never actually sent via sendMessage!
So every subsequent call logs "Skipping duplicate broadcast"
Robert 7 ماه پیش
والد
کامیت
360694eead
1فایلهای تغییر یافته به همراه24 افزوده شده و 3 حذف شده
  1. 24 3
      Trio/Sources/Services/WatchManager/GarminManager.swift

+ 24 - 3
Trio/Sources/Services/WatchManager/GarminManager.swift

@@ -1128,9 +1128,6 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable, @unchecked S
 
         lastSentHashLock.lock()
         let isDuplicate = (lastSentDataHash == currentHash)
-        if !isDuplicate {
-            lastSentDataHash = currentHash
-        }
         lastSentHashLock.unlock()
 
         if isDuplicate {
@@ -1138,6 +1135,9 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable, @unchecked S
             return
         }
 
+        // Store hash - will be marked as "sent" only after successful transmission
+        let hashToSend = currentHash
+
         // Update display types in the state before sending (handles cached/throttled data)
         let updatedState = updateDisplayTypesInState(state)
 
@@ -1167,6 +1167,8 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable, @unchecked S
             // 1. If it's a datafield, ALWAYS send (no status check)
             if isDatafieldApp {
                 debug(.watchManager, "[\(formatTimeForLog())] Garmin: Sending to datafield \(app.uuid!) (no status check)")
+                // Store hash to mark as sent on successful send
+                currentSendHash = hashToSend
                 sendMessage(updatedState, to: app)
                 return
             }
@@ -1193,6 +1195,8 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable, @unchecked S
                 }
 
                 debug(.watchManager, "[\(self.formatTimeForLog())] Garmin: Sending to watchface \(app.uuid!)")
+                // Store hash to mark as sent on successful send
+                self.currentSendHash = hashToSend
                 self.sendMessage(updatedState, to: app)
             }
         }
@@ -1330,6 +1334,15 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable, @unchecked S
         set { triggerLock.withLock { _currentSendTrigger = newValue } }
     }
 
+    // Track hash of data currently being sent (thread-safe)
+    private let sendHashLock = OSAllocatedUnfairLock()
+    private var _currentSendHash: Int?
+
+    private var currentSendHash: Int? {
+        get { sendHashLock.withLock { _currentSendHash } }
+        set { sendHashLock.withLock { _currentSendHash = newValue } }
+    }
+
     // Track connection health
     private var lastSuccessfulSendTime: Date?
     private var failedSendCount = 0
@@ -1372,6 +1385,14 @@ final class BaseGarminManager: NSObject, GarminManager, Injectable, @unchecked S
                     self.failedSendCount = 0
                     self.lastSuccessfulSendTime = Date()
                     self.connectionAlertShown = false // Reset alert flag on success
+
+                    // Mark hash as sent only after successful transmission
+                    if let sentHash = self.currentSendHash {
+                        self.lastSentHashLock.lock()
+                        self.lastSentDataHash = sentHash
+                        self.lastSentHashLock.unlock()
+                    }
+
                     debug(
                         .watchManager,
                         "[\(self.formatTimeForLog())] Garmin: Successfully sent message to \(app.uuid!) [Trigger: \(self.currentSendTrigger)]"