diff --git a/LoopCore/PersistenceController.swift b/LoopCore/PersistenceController.swift index 84c40b611..7f4e1d993 100644 --- a/LoopCore/PersistenceController.swift +++ b/LoopCore/PersistenceController.swift @@ -21,13 +21,13 @@ extension PersistenceController { return self.init(directoryURL: directoryURL.appendingPathComponent("com.loopkit.LoopKit", isDirectory: true), isReadOnly: isReadOnly) } - public class func controllerInLocalDirectory() -> PersistenceController { + public class func controllerInLocalDirectory(named name: String = "com.loopkit.LoopKit") -> PersistenceController { guard let directoryURL = try? FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else { fatalError("Could not access the document directory of the current process") } let isReadOnly = Bundle.main.isAppExtension - return self.init(directoryURL: directoryURL.appendingPathComponent("com.loopkit.LoopKit"), isReadOnly: isReadOnly) + return self.init(directoryURL: directoryURL.appendingPathComponent(name), isReadOnly: isReadOnly) } } diff --git a/WatchApp Extension/Managers/LoopDataManager.swift b/WatchApp Extension/Managers/LoopDataManager.swift index 4109d3f0b..1746cf8ce 100644 --- a/WatchApp Extension/Managers/LoopDataManager.swift +++ b/WatchApp Extension/Managers/LoopDataManager.swift @@ -111,10 +111,17 @@ class LoopDataManager { loopSettings: LoopSettings(), scheduleOverride: nil ) - + + // Give GlucoseStore its own Core Data stack rather than sharing `cacheStore` with + // CarbStore. GlucoseStore drives its context exclusively with the async + // `context.perform` API, while CarbStore uses `performAndWait`. Sharing one serial + // context between the two mixes those concurrency models and can race, producing a + // torn read of a freshly-inserted CachedGlucoseObject (a nil required attribute). + // A dedicated context removes that cross-store contention. + let glucoseCacheStore = PersistenceController.controllerInLocalDirectory(named: "com.loopkit.LoopKit.Glucose") Task { glucoseStore = await GlucoseStore( - cacheStore: cacheStore, + cacheStore: glucoseCacheStore, cacheLength: .hours(4) ) }