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

Force loop at pump error or time out. Potentialy this decrease yellow/red loops count

Ivan Valkou пре 4 година
родитељ
комит
c1ad93a1fb
1 измењених фајлова са 36 додато и 5 уклоњено
  1. 36 5
      FreeAPS/Sources/APS/DeviceDataManager.swift

+ 36 - 5
FreeAPS/Sources/APS/DeviceDataManager.swift

@@ -49,6 +49,8 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
     let bolusTrigger = PassthroughSubject<Bool, Never>()
     let errorSubject = PassthroughSubject<Error, Never>()
     let pumpNewStatus = PassthroughSubject<Void, Never>()
+    @SyncAccess private var pumpUpdateCancellable: AnyCancellable?
+    private var pumpUpdatePromise: Future<Bool, Never>.Promise?
 
     var pumpManager: PumpManagerUI? {
         didSet {
@@ -97,6 +99,13 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
     }
 
     func heartbeat(date: Date) {
+        guard pumpUpdateCancellable == nil else {
+            warning(.deviceManager, "Pump updating already in progress")
+            return
+        }
+
+        func update(_: Future<Bool, Never>.Promise?) {}
+
         processQueue.safeSync {
             lastHeartBeatTime = date
             updatePumpData()
@@ -106,16 +115,34 @@ final class BaseDeviceDataManager: DeviceDataManager, Injectable {
     private func updatePumpData() {
         guard let pumpManager = pumpManager else {
             debug(.deviceManager, "Pump is not set, skip updating")
+            updateUpdateFinished(false)
             return
         }
 
         debug(.deviceManager, "Start updating the pump data")
 
-        pumpManager.ensureCurrentPumpData {
-            debug(.deviceManager, "Pump Data updated")
+        pumpManager.ensureCurrentPumpData { [unowned self] in
+            debug(.deviceManager, "Pump data updated. Waiting for loop recommendation")
+            self.pumpUpdateCancellable = Future<Bool, Never> { promise in
+                self.pumpUpdatePromise = promise
+            }
+            .timeout(60, scheduler: self.processQueue)
+            .replaceError(with: false)
+            .replaceEmpty(with: false)
+            .sink(receiveValue: self.updateUpdateFinished)
         }
     }
 
+    private func updateUpdateFinished(_ recommendsLoop: Bool) {
+        pumpUpdateCancellable = nil
+        pumpUpdatePromise = nil
+        if !recommendsLoop {
+            warning(.deviceManager, "Loop recommendation time out or got error. Starting loop right now.")
+        }
+
+        self.recommendsLoop.send()
+    }
+
     private func pumpManagerFromRawValue(_ rawValue: [String: Any]) -> PumpManagerUI? {
         guard let rawState = rawValue["state"] as? PumpManager.RawStateValue,
               let Manager = pumpManagerTypeFromRawValue(rawValue)
@@ -215,7 +242,7 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
     }
 
     func pumpManagerBLEHeartbeatDidFire(_: PumpManager) {
-        debug(.deviceManager, "Pump Heartbeat")
+        debug(.deviceManager, "Pump Heartbeat: do nothing. Pump connection is OK")
     }
 
     func pumpManagerMustProvideBLEHeartbeat(_: PumpManager) -> Bool {
@@ -312,8 +339,12 @@ extension BaseDeviceDataManager: PumpManagerDelegate {
 
     func pumpManagerRecommendsLoop(_: PumpManager) {
         dispatchPrecondition(condition: .onQueue(processQueue))
-        debug(.deviceManager, "Recomends loop")
-        recommendsLoop.send()
+        debug(.deviceManager, "Pump recommends loop")
+        guard let promise = pumpUpdatePromise else {
+            warning(.deviceManager, "We do not waiting for loop recommendation at this time.")
+            return
+        }
+        promise(.success(true))
     }
 
     func startDateToFilterNewPumpEvents(for _: PumpManager) -> Date {