|
492
|
492
|
`deleteCache` should use a dedicated background context and perform all Core
|
|
493
|
493
|
Data mutations on that context's queue.
|
|
494
|
494
|
|
|
|
495
|
+### 2026-06-03 No Crash, But Snapshot Detail Lost Data Types
|
|
|
496
|
+
|
|
|
497
|
+Commit context: after disabling automatic/legacy Core Data cache work. Source:
|
|
|
498
|
+three user-provided reports and a screenshot of `SnapshotArchiveDetailView`.
|
|
|
499
|
+
|
|
|
500
|
+Observed sequence:
|
|
|
501
|
+
|
|
|
502
|
+| Time | Total records | Duration | Notes |
|
|
|
503
|
+|------|---------------|----------|-------|
|
|
|
504
|
+| 13:36 | 1,579,596 | 36.2s | Successful incremental snapshot, no crash. |
|
|
|
505
|
+| 13:45 | 1,579,601 | 31.3s | Not a true no-delta run: +5 records versus the prior snapshot. |
|
|
|
506
|
+| 13:47 | 1,579,601 | 2.5s | True no-delta run; processing and insert were 0.0s, finalize about 2.0s. |
|
|
|
507
|
+
|
|
|
508
|
+The detail screen showed `Metrics: 15`, `Records: 1579596`, and
|
|
|
509
|
+`Record Changes: 175`, but `Data Range` and `Data Types` were empty.
|
|
|
510
|
+
|
|
|
511
|
+Conclusion: the archive/import path is working, and no-delta is now fast. The
|
|
|
512
|
+UI regression came from remaining reads of `CachedTypeSummary` and
|
|
|
513
|
+`CachedDiffSummary` through `CoreDataArchiveCacheStore`. Since automatic cache
|
|
|
514
|
+rebuild is intentionally disabled to prevent freezes/crashes, snapshot detail,
|
|
|
515
|
+Data Types, drilldown screens, and charts must read materialized SQLite archive
|
|
|
516
|
+summaries directly. Do not re-enable automatic full Core Data rebuild as a fix
|
|
|
517
|
+for missing UI details.
|
|
|
518
|
+
|
|
495
|
519
|
## Optimization Iterations
|
|
496
|
520
|
|
|
497
|
521
|
| Date | Commit | Change | Result / Status |
|
|
521
|
545
|
| 2026-06-03 | `1229f19` | Disable legacy SwiftData detail-cache precompute completely and load Snapshots timeline from SQLite. | Triggered by overnight crash after two small detail caches were built. Expected signal: no `healthKit.detailCache.buildBegin` logs during snapshot save, no Core Data mutated-while-enumerated abort, and the new SQLite observation appears in Snapshots without waiting for cache rebuild. |
|
|
522
|
546
|
| 2026-06-03 | `199d2ef` | Stop automatic Dashboard Core Data cache rebuild after snapshot; refresh latest rows from SQLite only. | Triggered by freeze after copying a successful diagnostic report. Expected signal: copying diagnostics and returning to Dashboard/Snapshots remains responsive; Core Data cache rebuild is no longer started automatically after snapshot completion. |
|
|
523
|
547
|
| 2026-06-03 | `3abf63d` | Run Core Data cache rebuild/delete on a dedicated background context. | Triggered by `EXC_BAD_ACCESS` inside Core Data object insertion during cache rebuild. Expected signal: manual Settings cache rebuild no longer crashes due to `NSManagedObjectContext` queue misuse. |
|
|
|
548
|
+| 2026-06-03 | `2a82f67` | Load snapshot/type detail UI from SQLite materialized summaries instead of Core Data cache. | Triggered by successful snapshots whose detail screens showed no data types after automatic cache rebuild was disabled. Expected signal: Snapshot detail, Data Types, per-type drilldown, and evolution chart show current archive details without rebuilding Core Data cache. |
|
|
524
|
549
|
|
|
525
|
550
|
## Current Diagnosis
|
|
526
|
551
|
|
|
547
|
572
|
use SQLite summary rows only.
|
|
548
|
573
|
- Core Data cache rebuild must not mutate `viewContext` from background Swift
|
|
549
|
574
|
tasks. Rebuild/delete should use a private background context.
|
|
|
575
|
+- Snapshot and Data Types UI must not rely on Core Data cache rows being present.
|
|
|
576
|
+ SQLite observation rows and type summaries are already materialized during
|
|
|
577
|
+ archive finalization and should be the primary UI source for fresh snapshots.
|
|
550
|
578
|
|
|
551
|
579
|
## Open Issues / Observations
|
|
552
|
580
|
|
|
570
|
598
|
1. Run an incremental snapshot after removing automatic Core Data cache rebuild.
|
|
571
|
599
|
Confirm there are no `healthKit.detailCache.buildBegin` logs, copying the
|
|
572
|
600
|
diagnostic report does not freeze the app, and Dashboard/Snapshots show the
|
|
573
|
|
- latest observation from SQLite.
|
|
|
601
|
+ latest observation from SQLite. Also verify Snapshot detail and Data Types
|
|
|
602
|
+ show per-type summaries without a manual cache rebuild.
|
|
574
|
603
|
2. Run a repeated no-delta benchmark after copying unchanged metric summaries and daily aggregates. Compare `SummedFinalizeElapsed`, `Heart Rate finalizeElapsed`, `Active Energy finalizeElapsed`, and wall clock.
|
|
575
|
604
|
3. Add or inspect timing around per-record processing for changed high-volume metrics, especially Heart Rate, to separate sample DTO/fingerprint work from SQLite idempotency checks.
|
|
576
|
605
|
4. Run a non-chain-start/full-scan benchmark after skipping unchanged `verified` events and fast-pathing already-open visibility ranges. Compare `SummedInsertElapsed`, `Heart Rate insertElapsed`, `Steps insertElapsed`, and `Walking + Running Distance insertElapsed`.
|