Browse Source

Renaming lane and kick

Jonas Björkert 7 months ago
parent
commit
9f953f8d53

+ 4 - 4
Trio.xcodeproj/project.pbxproj

@@ -606,7 +606,7 @@
 		DD82D4B82DCAB2BA00BAFC77 /* PropertyPersistentFlags.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD82D4B72DCAB2BA00BAFC77 /* PropertyPersistentFlags.swift */; };
 		DD868FD82E381A54005D3308 /* APNSJWTClaims.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD868FD72E381A54005D3308 /* APNSJWTClaims.swift */; };
 		DD88C8E22C50420800F2D558 /* DefinitionRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD88C8E12C50420800F2D558 /* DefinitionRow.swift */; };
-		DD906BF42EA6AA0100262772 /* NightscoutLane.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD906BF32EA6AA0100262772 /* NightscoutLane.swift */; };
+		DD906BF42EA6AA0100262772 /* NightscoutUploadPipeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD906BF32EA6AA0100262772 /* NightscoutUploadPipeline.swift */; };
 		DD906BF62EA6AAE900262772 /* BaseNightscoutManager+Subscribers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD906BF52EA6AAE900262772 /* BaseNightscoutManager+Subscribers.swift */; };
 		DD940BAA2CA7585D000830A5 /* GlucoseColorScheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */; };
 		DD940BAC2CA75889000830A5 /* DynamicGlucoseColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD940BAB2CA75889000830A5 /* DynamicGlucoseColor.swift */; };
@@ -1434,7 +1434,7 @@
 		DD82D4B72DCAB2BA00BAFC77 /* PropertyPersistentFlags.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyPersistentFlags.swift; sourceTree = "<group>"; };
 		DD868FD72E381A54005D3308 /* APNSJWTClaims.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APNSJWTClaims.swift; sourceTree = "<group>"; };
 		DD88C8E12C50420800F2D558 /* DefinitionRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefinitionRow.swift; sourceTree = "<group>"; };
-		DD906BF32EA6AA0100262772 /* NightscoutLane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutLane.swift; sourceTree = "<group>"; };
+		DD906BF32EA6AA0100262772 /* NightscoutUploadPipeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NightscoutUploadPipeline.swift; sourceTree = "<group>"; };
 		DD906BF52EA6AAE900262772 /* BaseNightscoutManager+Subscribers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BaseNightscoutManager+Subscribers.swift"; sourceTree = "<group>"; };
 		DD940BA92CA7585D000830A5 /* GlucoseColorScheme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlucoseColorScheme.swift; sourceTree = "<group>"; };
 		DD940BAB2CA75889000830A5 /* DynamicGlucoseColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicGlucoseColor.swift; sourceTree = "<group>"; };
@@ -3474,7 +3474,7 @@
 		DDC9B9962CFD2332003E7721 /* Nightscout */ = {
 			isa = PBXGroup;
 			children = (
-				DD906BF32EA6AA0100262772 /* NightscoutLane.swift */,
+				DD906BF32EA6AA0100262772 /* NightscoutUploadPipeline.swift */,
 				3811DE9725C9D88300A708ED /* NightscoutManager.swift */,
 				38FE826C25CC8461001FF17A /* NightscoutAPI.swift */,
 				DD906BF52EA6AAE900262772 /* BaseNightscoutManager+Subscribers.swift */,
@@ -4135,7 +4135,7 @@
 				F90692CF274B999A0037068D /* HealthKitDataFlow.swift in Sources */,
 				CE7CA3552A064973004BE681 /* ListStateIntent.swift in Sources */,
 				C28DD7262DBA9A9E00EC02DD /* GlucosePercentileDetailView.swift in Sources */,
-				DD906BF42EA6AA0100262772 /* NightscoutLane.swift in Sources */,
+				DD906BF42EA6AA0100262772 /* NightscoutUploadPipeline.swift in Sources */, 
 				BDF530D82B40F8AC002CAF43 /* LockScreenView.swift in Sources */,
 				195D80B72AF697B800D25097 /* DynamicSettingsDataFlow.swift in Sources */,
 				DD98ACC02D71013200C0778F /* StatChartUtils.swift in Sources */,

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

@@ -5,85 +5,85 @@ 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
+    /// 2) Core Data change triggers → requests per upload pipeline
+    /// 3) Glucose storage updates → request glucose pipeline
     func wireSubscribers() {
         wireExternalUploadRequests()
         wireCoreDataSubscribers()
         wireGlucoseStorageSubscriber()
     }
 
-    /// Listens for `.nightscoutUploadRequested`, converts userInfo lanes to enums,
-    /// and kicks those lanes. Posts `.nightscoutUploadDidFinish` after enqueuing.
+    /// Listens for `.nightscoutUploadRequested`, converts userInfo pipelines to enums,
+    /// and requests those upload pipelines. Posts `.nightscoutUploadDidFinish` after enqueuing.
     func wireExternalUploadRequests() {
         Foundation.NotificationCenter.default.publisher(for: .nightscoutUploadRequested)
             .sink { [weak self] note in
                 guard let self else { return }
-                let lanes = (note.userInfo?[NightscoutNotificationKey.lanes] as? [String])?
-                    .compactMap(NightscoutLane.init(rawValue:)) ?? []
+                let pipelines = (note.userInfo?[NightscoutNotificationKey.uploadPipelines] as? [String])?
+                    .compactMap(NightscoutUploadPipeline.init(rawValue:)) ?? []
 
-                for lane in lanes { self.kick(lane) }
+                for pipeline in pipelines { self.requestUpload(pipeline) }
 
-                var info: [AnyHashable: Any] = [NightscoutNotificationKey.lanes: lanes.map(\.rawValue)]
+                var info: [AnyHashable: Any] = [NightscoutNotificationKey.uploadPipelines: pipelines.map(\.rawValue)]
                 if let src = note.userInfo?[NightscoutNotificationKey.source] { info[NightscoutNotificationKey.source] = src }
                 Foundation.NotificationCenter.default.post(name: .nightscoutUploadDidFinish, object: nil, userInfo: info)
             }
             .store(in: &subscriptions)
     }
 
-    /// Maps Core Data entity changes into lane kicks. We rely on
-    /// per-lane throttle so rapid changes don’t spam Nightscout.
+    /// Maps Core Data entity changes into upload pipeline requests. We rely on
+    /// per-pipeline throttle so rapid changes don’t spam Nightscout.
     func wireCoreDataSubscribers() {
         coreDataPublisher?
             .filteredByEntityName("OrefDetermination")
-            .sink { [weak self] _ in self?.kick(.deviceStatus) }
+            .sink { [weak self] _ in self?.requestUpload(.deviceStatus) }
             .store(in: &subscriptions)
 
         coreDataPublisher?
             .filteredByEntityName("OverrideStored")
-            .sink { [weak self] _ in self?.kick(.overrides) }
+            .sink { [weak self] _ in self?.requestUpload(.overrides) }
             .store(in: &subscriptions)
 
         coreDataPublisher?
             .filteredByEntityName("OverrideRunStored")
-            .sink { [weak self] _ in self?.kick(.overrides) }
+            .sink { [weak self] _ in self?.requestUpload(.overrides) }
             .store(in: &subscriptions)
 
         coreDataPublisher?
             .filteredByEntityName("TempTargetStored")
-            .sink { [weak self] _ in self?.kick(.tempTargets) }
+            .sink { [weak self] _ in self?.requestUpload(.tempTargets) }
             .store(in: &subscriptions)
 
         coreDataPublisher?
             .filteredByEntityName("TempTargetRunStored")
-            .sink { [weak self] _ in self?.kick(.tempTargets) }
+            .sink { [weak self] _ in self?.requestUpload(.tempTargets) }
             .store(in: &subscriptions)
 
         coreDataPublisher?
             .filteredByEntityName("PumpEventStored")
-            .sink { [weak self] _ in self?.kick(.pumpHistory) }
+            .sink { [weak self] _ in self?.requestUpload(.pumpHistory) }
             .store(in: &subscriptions)
 
         coreDataPublisher?
             .filteredByEntityName("CarbEntryStored")
-            .sink { [weak self] _ in self?.kick(.carbs) }
+            .sink { [weak self] _ in self?.requestUpload(.carbs) }
             .store(in: &subscriptions)
 
         coreDataPublisher?
             .filteredByEntityName("GlucoseStored")
             .sink { [weak self] _ in
-                self?.kick(.glucose)
-                self?.kick(.manualGlucose)
+                self?.requestUpload(.glucose)
+                self?.requestUpload(.manualGlucose)
             }
             .store(in: &subscriptions)
     }
 
-    /// Glucose storage updates → kick glucose lane
+    /// Glucose storage updates → request glucose pipeline
     func wireGlucoseStorageSubscriber() {
         glucoseStorage.updatePublisher
             .receive(on: queue)
             .sink { [weak self] _ in
-                self?.kick(.glucose)
+                self?.requestUpload(.glucose)
             }
             .store(in: &subscriptions)
     }

+ 22 - 22
Trio/Sources/Services/Network/Nightscout/NightscoutManager.swift

@@ -44,52 +44,52 @@ 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)
+    // Queue where upload pipelines run.
+    let uploadPipelineQueue = DispatchQueue(label: "NightscoutManager.uploadPipelines", 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] = [
+    /// Throttle window (seconds) per upload pipeline. Any requests inside this window
+    /// coalesce into a single upload run for that pipeline.
+    let uploadPipelineInterval: [NightscoutUploadPipeline: 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
+    /// Subjects used to request an upload pipeline. 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>() }
+    var uploadPipelineSubjects: [NightscoutUploadPipeline: PassthroughSubject<Void, Never>] = {
+        var d: [NightscoutUploadPipeline: PassthroughSubject<Void, Never>] = [:]
+        NightscoutUploadPipeline.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(())
+    /// Request an upload for a pipeline (enqueue work). Safe to call from anywhere.
+    func requestUpload(_ uploadPipeline: NightscoutUploadPipeline) {
+        uploadPipelineSubjects[uploadPipeline]?.send(())
     }
 
-    /// Build the Combine pipelines for all lanes: subject → throttle → upload.
+    /// Build the Combine pipelines for all upload pipelines: 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 }
+        for pipeline in NightscoutUploadPipeline.allCases {
+            guard let subject = uploadPipelineSubjects[pipeline], let window = uploadPipelineInterval[pipeline] else { continue }
             subject
-                .receive(on: laneQueue)
-                .throttle(for: .seconds(window), scheduler: laneQueue, latest: false)
+                .receive(on: uploadPipelineQueue)
+                .throttle(for: .seconds(window), scheduler: uploadPipelineQueue, latest: false)
                 .sink { [weak self] in
                     guard let self else { return }
-                    Task(priority: .utility) { await self.runLane(lane) }
+                    Task(priority: .utility) { await self.runUploadPipeline(pipeline) }
                 }
                 .store(in: &subscriptions)
         }
     }
 
-    /// Runs the actual upload for a single lane.
+    /// Runs the actual upload for a single upload pipeline.
     /// Called by the throttled pipeline, not directly by callers.
-    func runLane(_ lane: NightscoutLane) async {
-        switch lane {
+    func runUploadPipeline(_ uploadPipeline: NightscoutUploadPipeline) async {
+        switch uploadPipeline {
         case .carbs: await uploadCarbs()
         case .pumpHistory: await uploadPumpHistory()
         case .overrides: await uploadOverrides()
@@ -135,7 +135,7 @@ final class BaseNightscoutManager: NightscoutManager, Injectable {
     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.
+    /// and request upload pipelines based on what changed.
     var coreDataPublisher: AnyPublisher<Set<NSManagedObjectID>, Never>?
 
     /// Bag for Combine subscriptions owned by this manager.

+ 10 - 10
Trio/Sources/Services/Network/Nightscout/NightscoutLane.swift

@@ -1,9 +1,9 @@
 import Foundation
 
 /// Logical upload “paths” handled by NightscoutManager.
-/// Each lane has its own throttled queue so we don’t double-upload
+/// Each upload pipeline 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 {
+public enum NightscoutUploadPipeline: String, CaseIterable {
     case carbs
     case pumpHistory
     case overrides
@@ -15,28 +15,28 @@ public enum NightscoutLane: String, CaseIterable {
 
 /// Keys used in Nightscout upload notifications.
 public enum NightscoutNotificationKey {
-    /// Array of lane rawValues to upload, e.g. ["carbs", "pumpHistory"].
-    public static let lanes = "lanes"
+    /// Array of upload pipeline rawValues to upload, e.g. ["carbs", "pumpHistory"].
+    public static let uploadPipelines = "uploadPipelines"
     /// 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.
+    /// Post this to request one or more uploads by upload pipeline.
     static let nightscoutUploadRequested = Notification.Name("nightscoutUploadRequested")
-    /// Posted after we enqueue all requested lanes (not a network completion).
+    /// Posted after we enqueue all requested upload pipelines (not a network completion).
     static let nightscoutUploadDidFinish = Notification.Name("nightscoutUploadDidFinish")
 }
 
 /// Convenience helper any component (e.g. APSManager) can call to
-/// request uploads. The work is enqueued and deduped per lane via throttle,
+/// request uploads. The work is enqueued and deduped per upload pipeline via throttle,
 /// so rapid duplicate calls won’t double-upload.
 ///
 /// - Parameters:
-///   - lanes: Which lanes to kick (carbs, pumpHistory, etc).
+///   - uploadPipelines: Which pipelines to request (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)]
+public func requestNightscoutUpload(_ uploadPipelines: [NightscoutUploadPipeline], source: String? = nil) {
+    var userInfo: [AnyHashable: Any] = [NightscoutNotificationKey.uploadPipelines: uploadPipelines.map(\.rawValue)]
     if let source { userInfo[NightscoutNotificationKey.source] = source }
     Foundation.NotificationCenter.default.post(name: .nightscoutUploadRequested, object: nil, userInfo: userInfo)
 }