Просмотр исходного кода

Adding docstrings, no functional changes

Jonas Björkert 7 месяцев назад
Родитель
Сommit
1e5df936aa

+ 9 - 2
Trio/Sources/Services/Network/Nightscout/BaseNightscoutManager+Subscribers.swift

@@ -3,12 +3,18 @@ import CoreData
 import Foundation
 
 extension BaseNightscoutManager {
+    /// Call once from init. Hooks up:
+    /// 1) external upload requests (NotificationCenter)
+    /// 2) Core Data change triggers → kicks per lane
+    /// 3) Glucose storage updates → kick glucose lane
     func wireSubscribers() {
         wireExternalUploadRequests()
         wireCoreDataSubscribers()
         wireGlucoseStorageSubscriber()
     }
 
+    /// Listens for `.nightscoutUploadRequested`, converts userInfo lanes to enums,
+    /// and kicks those lanes. Posts `.nightscoutUploadDidFinish` after enqueuing.
     func wireExternalUploadRequests() {
         Foundation.NotificationCenter.default.publisher(for: .nightscoutUploadRequested)
             .sink { [weak self] note in
@@ -25,6 +31,8 @@ extension BaseNightscoutManager {
             .store(in: &subscriptions)
     }
 
+    /// Maps Core Data entity changes into lane kicks. We rely on
+    /// per-lane throttle so rapid changes don’t spam Nightscout.
     func wireCoreDataSubscribers() {
         coreDataPublisher?
             .filteredByEntityName("OrefDetermination")
@@ -70,8 +78,7 @@ extension BaseNightscoutManager {
             .store(in: &subscriptions)
     }
 
-    // MARK: 3) Glucose storage tick → kick glucose lane
-
+    /// Glucose storage updates → kick glucose lane
     func wireGlucoseStorageSubscriber() {
         glucoseStorage.updatePublisher
             .receive(on: queue)

+ 15 - 1
Trio/Sources/Services/Network/Nightscout/NightscoutLane.swift

@@ -1,5 +1,8 @@
 import Foundation
 
+/// Logical upload “paths” handled by NightscoutManager.
+/// Each lane has its own throttled queue so we don’t double-upload
+/// when multiple sources trigger the same work close together.
 public enum NightscoutLane: String, CaseIterable {
     case carbs
     case pumpHistory
@@ -10,17 +13,28 @@ public enum NightscoutLane: String, CaseIterable {
     case deviceStatus
 }
 
+/// Keys used in Nightscout upload notifications.
 public enum NightscoutNotificationKey {
+    /// Array of lane rawValues to upload, e.g. ["carbs", "pumpHistory"].
     public static let lanes = "lanes"
+    /// Optional string that says who asked for the upload (debug/diagnostics).
     public static let source = "source"
 }
 
 public extension Foundation.Notification.Name {
+    /// Post this to request one or more uploads by lane.
     static let nightscoutUploadRequested = Notification.Name("nightscoutUploadRequested")
+    /// Posted after we enqueue all requested lanes (not a network completion).
     static let nightscoutUploadDidFinish = Notification.Name("nightscoutUploadDidFinish")
 }
 
-/// Simple helper any component (e.g. APSManager) can call.
+/// Convenience helper any component (e.g. APSManager) can call to
+/// request uploads. The work is enqueued and deduped per lane via throttle,
+/// so rapid duplicate calls won’t double-upload.
+///
+/// - Parameters:
+///   - lanes: Which lanes to kick (carbs, pumpHistory, etc).
+///   - source: Optional tag for debugging (e.g. "APSManager").
 public func requestNightscoutUpload(_ lanes: [NightscoutLane], source: String? = nil) {
     var userInfo: [AnyHashable: Any] = [NightscoutNotificationKey.lanes: lanes.map(\.rawValue)]
     if let source { userInfo[NightscoutNotificationKey.source] = source }

+ 16 - 0
Trio/Sources/Services/Network/Nightscout/NightscoutManager.swift

@@ -44,25 +44,34 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     private let processQueue = DispatchQueue(label: "BaseNetworkManager.processQueue")
     private var ping: TimeInterval?
 
+    // Queue where lane pipelines run.
     let laneQueue = DispatchQueue(label: "NightscoutManager.lanes", qos: .utility)
 
+    // Background Core Data context for fetches used by upload tasks.
     var backgroundContext = CoreDataStack.shared.newTaskContext()
 
+    /// Throttle window (seconds) per lane. Any kicks inside this window
+    /// coalesce into a single upload run for that lane.
     let laneInterval: [NightscoutLane: TimeInterval] = [
         .carbs: 2, .pumpHistory: 2, .overrides: 2, .tempTargets: 2,
         .glucose: 2, .manualGlucose: 2, .deviceStatus: 2
     ]
 
+    /// Subjects used to “kick” a lane. The pipeline applies a throttle so
+    /// close calls don’t double-upload.
     var laneSubjects: [NightscoutLane: PassthroughSubject<Void, Never>] = {
         var d: [NightscoutLane: PassthroughSubject<Void, Never>] = [:]
         NightscoutLane.allCases.forEach { d[$0] = PassthroughSubject<Void, Never>() }
         return d
     }()
 
+    /// Send a kick for a lane (enqueue work). Safe to call from anywhere.
     func kick(_ lane: NightscoutLane) {
         laneSubjects[lane]?.send(())
     }
 
+    /// Build the Combine pipelines for all lanes: subject → throttle → upload.
+    /// Must be called once during init().
     func setupLanePipelines() {
         for lane in NightscoutLane.allCases {
             guard let subject = laneSubjects[lane], let window = laneInterval[lane] else { continue }
@@ -77,6 +86,8 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
         }
     }
 
+    /// Runs the actual upload for a single lane.
+    /// Called by the throttled pipeline, not directly by callers.
     func runLane(_ lane: NightscoutLane) async {
         switch lane {
         case .carbs: await uploadCarbs()
@@ -122,7 +133,12 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
 
     // Queue for handling Core Data change notifications
     let queue = DispatchQueue(label: "BaseNightscoutManager.queue", qos: .utility)
+
+    /// Emits changed Core Data object IDs from the app. We filter by entity names
+    /// and kick lanes based on what changed.
     var coreDataPublisher: AnyPublisher<Set<NSManagedObjectID>, Never>?
+
+    /// Bag for Combine subscriptions owned by this manager.
     var subscriptions = Set<AnyCancellable>()
 
     init(resolver: Resolver) {