From 0f9a94045663a75daf31b6740585d5f098b4f729 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Bj=C3=B6rkert?= Date: Thu, 9 Apr 2026 15:50:28 +0200 Subject: [PATCH] Route remote command polling through TaskScheduler Replace the parallel Timer with a .remoteCommandPoll TaskScheduler task so the aggressive post-remote-command polling runs through the same scheduler as every other recurring fetch. The tick reschedules .deviceStatus and .treatments to fire immediately, then reschedules itself for the next interval. Parked at .distantFuture when the window closes (timeout or fresh data detected). Drop .fetchBG from the polled set: no remote command produces a BG entry, and the completion signature doesn't look at bgData, so the fetch was dead weight during the window. --- LoopFollow/Task/TaskScheduler.swift | 1 + .../ViewControllers/MainViewController.swift | 25 ++++++++----------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/LoopFollow/Task/TaskScheduler.swift b/LoopFollow/Task/TaskScheduler.swift index a18b92aa3..99573160c 100644 --- a/LoopFollow/Task/TaskScheduler.swift +++ b/LoopFollow/Task/TaskScheduler.swift @@ -12,6 +12,7 @@ enum TaskID: CaseIterable { case minAgoUpdate case calendarWrite case alarmCheck + case remoteCommandPoll } struct ScheduledTask { diff --git a/LoopFollow/ViewControllers/MainViewController.swift b/LoopFollow/ViewControllers/MainViewController.swift index ce8e04342..1ae406544 100644 --- a/LoopFollow/ViewControllers/MainViewController.swift +++ b/LoopFollow/ViewControllers/MainViewController.swift @@ -169,7 +169,6 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele "deviceStatus": false, ] private var loadingTimeoutTimer: Timer? - private var remoteCommandPollingTimer: Timer? private var remoteCommandPollingStartedAt: Date? private var remoteCommandPollingBaseline: RemoteCommandDataSignature? private let remoteCommandPollingInterval: TimeInterval = 3 @@ -869,7 +868,6 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele } deinit { - remoteCommandPollingTimer?.invalidate() NotificationCenter.default.removeObserver(self, name: NSNotification.Name("refresh"), object: nil) } @@ -915,26 +913,20 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele remoteCommandPollingBaseline = currentRemoteCommandDataSignature() remoteCommandPollingStartedAt = Date() - remoteCommandPollingTimer?.invalidate() - performRemoteCommandPollingTick() - - let timer = Timer.scheduledTimer(withTimeInterval: remoteCommandPollingInterval, repeats: true) { [weak self] _ in + TaskScheduler.shared.scheduleTask(id: .remoteCommandPoll, nextRun: Date()) { [weak self] in self?.performRemoteCommandPollingTick() } - timer.tolerance = 0.5 - remoteCommandPollingTimer = timer LogManager.shared.log(category: .general, message: "Started aggressive polling after remote command result notification") } private func stopRemoteCommandPolling(reason: String) { - guard remoteCommandPollingTimer != nil || remoteCommandPollingStartedAt != nil else { return } + guard remoteCommandPollingStartedAt != nil else { return } - remoteCommandPollingTimer?.invalidate() - remoteCommandPollingTimer = nil remoteCommandPollingStartedAt = nil remoteCommandPollingBaseline = nil + TaskScheduler.shared.rescheduleTask(id: .remoteCommandPoll, to: .distantFuture) LogManager.shared.log(category: .general, message: "Stopped aggressive polling: \(reason)") } @@ -947,9 +939,14 @@ class MainViewController: UIViewController, UITableViewDataSource, ChartViewDele return } - bgTaskAction() - deviceStatusAction() - treatmentsTaskAction() + let now = Date() + TaskScheduler.shared.rescheduleTask(id: .deviceStatus, to: now) + TaskScheduler.shared.rescheduleTask(id: .treatments, to: now) + + TaskScheduler.shared.rescheduleTask( + id: .remoteCommandPoll, + to: Date().addingTimeInterval(remoteCommandPollingInterval) + ) } private func currentRemoteCommandDataSignature() -> RemoteCommandDataSignature {