Skip to content

Commit 6382e24

Browse files
authored
Merge pull request #379 from loopandlearn/task-improvements
Task improvements
2 parents d1f4091 + 3203d8b commit 6382e24

File tree

3 files changed

+36
-14
lines changed

3 files changed

+36
-14
lines changed

LoopFollow/Controllers/BackgroundAlertManager.swift

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import UserNotifications
1111

1212
/// Enum representing different background alert durations.
1313
enum BackgroundAlertDuration: TimeInterval, CaseIterable {
14-
case sixMinutes = 360 // 6 minutes in seconds
14+
case sixMinutes = 360 // 6 minutes in seconds
1515
case twelveMinutes = 720 // 12 minutes in seconds
1616
case eighteenMinutes = 1080 // 18 minutes in seconds
1717
}
@@ -34,10 +34,14 @@ class BackgroundAlertManager {
3434
/// Title prefix for all background refresh notifications.
3535
private let notificationTitlePrefix = "LoopFollow Background Refresh"
3636

37+
/// Timestamp of the last scheduled background alert.
38+
private var lastScheduleDate: Date?
39+
3740
/// Start scheduling background alerts.
3841
func startBackgroundAlert() {
3942
isAlertScheduled = true
40-
scheduleBackgroundAlert()
43+
// Force execution to bypass throttle when starting
44+
scheduleBackgroundAlert(force: true)
4145
}
4246

4347
/// Stop all scheduled background alerts.
@@ -48,11 +52,21 @@ class BackgroundAlertManager {
4852
}
4953

5054
/// (Re)schedule all background alerts based on predefined durations.
51-
func scheduleBackgroundAlert() {
52-
removeDeliveredNotifications()
53-
55+
/// - Parameter force: When true, the scheduling is executed regardless of throttle constraints.
56+
func scheduleBackgroundAlert(force: Bool = false) {
5457
guard isAlertScheduled, Storage.shared.backgroundRefreshType.value != .none else { return }
5558

59+
// Throttle execution if not forced: only run once every 10 seconds.
60+
if !force {
61+
let now = Date()
62+
if let lastDate = lastScheduleDate, now.timeIntervalSince(lastDate) < 10 {
63+
return
64+
}
65+
lastScheduleDate = now
66+
}
67+
68+
removeDeliveredNotifications()
69+
5670
let isBluetoothActive = Storage.shared.backgroundRefreshType.value.isBluetooth
5771
let expectedHeartbeat = BLEManager.shared.expectedHeartbeatInterval()
5872

@@ -62,22 +76,22 @@ class BackgroundAlertManager {
6276
identifier: BackgroundAlertIdentifier.sixMin.rawValue,
6377
timeInterval: BackgroundAlertDuration.sixMinutes.rawValue,
6478
body: isBluetoothActive
65-
? "App inactive for 6 minutes. Verify Bluetooth connectivity."
66-
: "App inactive for 6 minutes. Open to resume."
79+
? "App inactive for 6 minutes. Verify Bluetooth connectivity."
80+
: "App inactive for 6 minutes. Open to resume."
6781
),
6882
BackgroundAlert(
6983
identifier: BackgroundAlertIdentifier.twelveMin.rawValue,
7084
timeInterval: BackgroundAlertDuration.twelveMinutes.rawValue,
7185
body: isBluetoothActive
72-
? "App inactive for 12 minutes. Verify Bluetooth connectivity."
73-
: "App inactive for 12 minutes. Open to resume."
86+
? "App inactive for 12 minutes. Verify Bluetooth connectivity."
87+
: "App inactive for 12 minutes. Open to resume."
7488
),
7589
BackgroundAlert(
7690
identifier: BackgroundAlertIdentifier.eighteenMin.rawValue,
7791
timeInterval: BackgroundAlertDuration.eighteenMinutes.rawValue,
7892
body: isBluetoothActive
79-
? "App inactive for 18 minutes. Verify Bluetooth connectivity."
80-
: "App inactive for 18 minutes. Open to resume."
93+
? "App inactive for 18 minutes. Verify Bluetooth connectivity."
94+
: "App inactive for 18 minutes. Open to resume."
8195
)
8296
]
8397

@@ -119,7 +133,7 @@ class BackgroundAlertManager {
119133
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers)
120134
}
121135

122-
/// Remove all delivered notifications
136+
/// Remove all delivered notifications.
123137
private func removeDeliveredNotifications() {
124138
let identifiers = BackgroundAlertIdentifier.allCases.map { $0.rawValue }
125139
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers)

LoopFollow/Controllers/Nightscout/DeviceStatus.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ extension MainViewController {
8686

8787
if jsonDeviceStatus.count == 0 {
8888
LogManager.shared.log(category: .deviceStatus, message: "Device status is empty")
89+
TaskScheduler.shared.rescheduleTask(id: .deviceStatus, to: Date().addingTimeInterval(5 * 60))
8990
return
9091
}
9192

LoopFollow/Task/TaskScheduler.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,15 +107,22 @@ class TaskScheduler {
107107
continue
108108
}
109109

110-
// Check if we should skip alarmCheck
110+
// Check if we should re-schedule alarmCheck till after other tasks are done
111111
if taskID == .alarmCheck {
112112
let shouldSkip = tasksToSkipAlarmCheck.contains {
113113
guard let checkTask = tasks[$0] else { return false }
114114
return checkTask.nextRun <= now || checkTask.nextRun == .distantFuture
115115
}
116116

117117
if shouldSkip {
118-
//LogManager.shared.log(category: .taskScheduler, message: "Skipping alarmCheck because one of the specified tasks is due or set to distant future.")
118+
//LogManager.shared.log(category: .taskScheduler, message: "Skipping alarmCheck because one of the specified tasks is due or set to distant future.", isDebug: true)
119+
120+
guard var existingTask = self.tasks[taskID] else {
121+
continue
122+
}
123+
existingTask.nextRun = Date().addingTimeInterval(5)
124+
self.tasks[taskID] = existingTask
125+
119126
continue
120127
}
121128
}

0 commit comments

Comments
 (0)