commit 31aedea53c1694c69a4b2a259c6c849ff47007fe
parent ebe8ff8782c9989a8bd3c37456c03fe37ed700de
Author: Michael Camilleri <[email protected]>
Date: Thu, 2 Jul 2026 09:03:42 +0900
Reuse the outbound record build context
This commit stops the sync send path from allocating a fresh Core Data
background context for every pending Game, Moves, Journal or Player
record in a CKSyncEngine batch. The previous path rebuilt the context
inside buildRecord, so a large drain paid that setup cost once per
record.
makeRecordZoneChangeBatch now creates the build context once and passes
it through to RecordBuilder. Ping and Decision records still use their
actor snapshots and do not touch Core Data.
Co-Authored-By: Codex GPT 5.5 <[email protected]>
Diffstat:
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/Crossmate/Sync/RecordBuilder.swift b/Crossmate/Sync/RecordBuilder.swift
@@ -9,6 +9,7 @@ extension SyncEngine {
/// since the framework calls back synchronously off-actor.
nonisolated func buildRecord(
for recordID: CKRecord.ID,
+ in ctx: NSManagedObjectContext,
pings: [String: PingPayload],
decisions: [String: String],
decisionVersions: [String: Int64],
@@ -45,7 +46,6 @@ extension SyncEngine {
version: decisionVersions[stateKey]
)
}
- let ctx = persistence.container.newBackgroundContext()
return ctx.performAndWait {
if name.hasPrefix("game-") {
let req = NSFetchRequest<GameEntity>(entityName: "GameEntity")
diff --git a/Crossmate/Sync/SyncEngine.swift b/Crossmate/Sync/SyncEngine.swift
@@ -2252,10 +2252,12 @@ extension SyncEngine: CKSyncEngineDelegate {
let decisionSnapshot = pendingDecisionPayloads
let decisionVersionSnapshot = pendingDecisionVersions
let decisionSystemFieldsSnapshot = decisionSystemFields
+ let buildContext = persistence.container.newBackgroundContext()
return await CKSyncEngine.RecordZoneChangeBatch(pendingChanges: pending) { [weak self] recordID in
guard let self else { return nil }
if let record = self.buildRecord(
for: recordID,
+ in: buildContext,
pings: pingSnapshot,
decisions: decisionSnapshot,
decisionVersions: decisionVersionSnapshot,