martini
martini

Reputation: 3

Ensembles: unnecessary round-trip(s) when syncing with CloudKit file system

I have integrated Ensembles v2.5 into my App and I am using the CloudKit file system. Merges are triggered automatically via push notifications as described in the Ensembles documentation.

In general syncing works, but my problem is that after a change is synced via CloudKit to the 2nd device, the 2nd device seems to upload new transaction logs to CloudKit which triggers another merge (via push notification) on the 1st device. Sometimes another merge is followed on the 2nd device, resulting in two unnecessary merges.

A practical example:
1) device 1 (iPad) makes a change
2) changes propagate to CloudKit
3) push notification triggers merge on device 2 (iPod Touch)

iPad and iPod Touch have the same data now and no more merges should occur, but:

4) iPod Touch creates new transaction logs
5) push notification triggers merge on iPad
6) iPad creates new transaction logs
7) push notification triggers merge iPod Touch

Here is the Ensembles trace on device 2 (iPod Touch)

18:16:28.202   Enqueuing merge                                               <<<  -[CDEPersistentStoreEnsemble mergeWithOptions:completion:]
18:16:28.215   Beginning merge                                               <<<  __47-[CDEPersistentStoreEnsemble newMergeSetupStep]_block_invoke
18:16:28.234   Priming CloudKit cache                                        <<<  -[CDECloudKitFileSystem primeForActivityWithCompletion:]
18:16:28.235   Beginning change processing for CloudKit.                     <<<  -[CDECloudKitFileSystem primeForActivityWithCompletion:]
18:16:28.872   Processed cloudkit change (insert/update): /DemoAppMainStore/events/33_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_21.cdeevent  <<<  __56-[CDECloudKitFileSystem primeForActivityWithCompletion:]_block_invoke
18:16:28.876   Completing CloudKit fetch record changes                      <<<  __56-[CDECloudKitFileSystem primeForActivityWithCompletion:]_block_invoke.311
18:16:28.887   Checking identity in cloud system                             <<<  -[CDEPersistentStoreEnsemble checkCloudFileSystemIdentityWithCompletion:]
18:16:29.314   Passed identity check with identity: <CKRecordID: 0x1660a840; _7fd2f6a37e22282e02a1d8fb52ba2d8e:(_defaultZone:__defaultOwner__)>  <<<  __73-[CDEPersistentStoreEnsemble checkCloudFileSystemIdentityWithCompletion:]_block_invoke
18:16:29.324   Checking registration info                                    <<<  -[CDEPersistentStoreEnsemble checkStoreRegistrationInCloudWithCompletion:]
18:16:29.325   Checking existence of registration info                       <<<  -[CDECloudManager checkExistenceOfRegistrationInfoForStoreWithIdentifier:completion:]
18:16:29.326   Checking existence of file: /DemoAppMainStore/stores/0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA  <<<  -[CDECloudKitFileSystem fileExistsAtPath:completion:]
18:16:29.329   Retrieving records for paths: (
    "/DemoAppMainStore/stores/0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA"
)  <<<  -[CDECloudKitFileSystem fetchRecordsAtPaths:completion:]
18:16:29.330   File exists. Is dir? 0                                        <<<  __53-[CDECloudKitFileSystem fileExistsAtPath:completion:]_block_invoke
18:16:29.343 Localizable string "(A Document Being Saved By %@)" not found in strings table "Document" of bundle CFBundle 0x166429d0 </System/Library/Frameworks/Foundation.framework> (not loaded).
18:16:29.380   Getting contents of directory at path: /DemoAppMainStore/baselines  <<<  -[CDECloudKitFileSystem contentsOfDirectoryAtPath:completion:]
18:16:29.383   Getting contents of directory at path: /DemoAppMainStore/events  <<<  -[CDECloudKitFileSystem contentsOfDirectoryAtPath:completion:]
18:16:29.386   Getting contents of directory at path: /DemoAppMainStore/data  <<<  -[CDECloudKitFileSystem contentsOfDirectoryAtPath:completion:]
18:16:29.394   Removing incomplete remote file sets                          <<<  -[CDECloudManager removeLocallyProducedIncompleteRemoteFileSets:]
18:16:29.447   Transferring new data files from cloud to event store         <<<  -[CDECloudManager importNewDataFilesWithProgress:]
18:16:29.459   Transferring new baselines from cloud to event store          <<<  -[CDECloudManager importNewBaselineEventsWithProgress:]
18:16:29.486   Consolidating baselines                                       <<<  -[CDEBaselineConsolidator consolidateBaselineWithCompletion:]
18:16:29.498   Found baselines with unique ids: (
    "848B3010-D3D0-4928-BFA9-249D2CE617A0-777-000002E2704C7408"
)  <<<  __61-[CDEBaselineConsolidator consolidateBaselineWithCompletion:]_block_invoke
18:16:29.499   Baselines remaining that need merging: 1                      <<<  __61-[CDEBaselineConsolidator consolidateBaselineWithCompletion:]_block_invoke
18:16:29.501   Finishing baseline consolidation                              <<<  __61-[CDEBaselineConsolidator consolidateBaselineWithCompletion:]_block_invoke_2
18:16:29.506   Transferring new events from cloud to event store             <<<  -[CDECloudManager importNewRemoteNonBaselineEventsWithProgress:]
18:16:29.588   Downloading files to transit cache: (
    "/DemoAppMainStore/events/33_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_21.cdeevent"
)  <<<  __83-[CDECloudManager downloadFiles:fromRemoteDirectory:batchCompletionBlock:progress:]_block_invoke_2
18:16:29.591   Downloading from paths (
    "/DemoAppMainStore/events/33_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_21.cdeevent"
) to path (
    "/var/mobile/Containers/Data/Application/3EA6BB44-7135-4C5D-91D3-D36878005B1C/Library/Application Support/ch.appzoo.DemoApp/com.mentalfaculty.ensembles.eventdata/transitcache/DemoAppMainStore/download/33_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_21.cdeevent"
)  <<<  -[CDECloudKitFileSystem downloadFromPaths:toLocalFiles:completion:]
18:16:32.120   Migrating event in to event store from files: (
    "33_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_21.cdeevent"
)  <<<  __84-[CDECloudManager migrateNewEventsWhichAreBaselines:fromTransitCacheWithCompletion:]_block_invoke.292
18:16:32.121   Migrating events in from files                                <<<  -[CDEEventMigrator migrateEventInFromFileURLs:completion:]
18:16:32.124   Migrating file events to event store                          <<<  -[CDEEventImport main]
18:16:32.125   Importing file at URL: file:///var/mobile/Containers/Data/Application/3EA6BB44-7135-4C5D-91D3-D36878005B1C/Library/Application%20Support/ch.appzoo.DemoApp/com.mentalfaculty.ensembles.eventdata/transitcache/DemoAppMainStore/download/33_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_21.cdeevent  <<<  __22-[CDEEventImport main]_block_invoke.22
18:16:32.382   Determining events to include in integration                  <<<  -[CDEEventIntegrator storeModificationEventIDsForIntegration:]
18:16:32.546   Including these events in the integration: (
    "<CDEStoreModificationEvent: 0x167b3590> (entity: CDEStoreModificationEvent; id: 0x167d6720 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEStoreModificationEvent/p37> ; data: {\n    eventRevision = \"0x167a7280 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEEventRevision/p72>\";\n    eventRevisionsOfOtherStores =     (\n        \"0x167ddf40 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEEventRevision/p71>\"\n    );\n    globalCount = 32;\n    modelVersion = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<!DOCTYPE plist PUBLIC \\\"-//Apple//DTD PLIST 1.0//EN\\\" \\\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\\">\\n<plist version=\\\"1.0\\\">\\n<dict>\\n\\t<key>DMBuddy</key>\\n\\t<data>\\n\\t\";\n    objectChanges = \"<relationship fault: 0x17878a60 'objectChanges'>\";\n    timestamp = \"16:49:55 +0000\";\n    type = 300;\n    uniqueIdentifier = \"E432A13E-3825-4833-A306-F84044492252-498-0000010ED9BE7E88\";\n})",
    "<CDEStoreModificationEvent: 0x167b3620> (entity: CDEStoreModificationEvent; id: 0x16730ac0 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEStoreModificationEvent/p38> ; data: {\n    eventRevision = \"0x166b4420 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEEventRevision/p73>\";\n    eventRevisionsOfOtherStores =     (\n        \"0x167ecb10 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEEventRevision/p74>\"\n    );\n    globalCount = 33;\n    modelVersion = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<!DOCTYPE plist PUBLIC \\\"-//Apple//DTD PLIST 1.0//EN\\\" \\\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\\">\\n<plist version=\\\"1.0\\\">\\n<dict>\\n\\t<key>DMBuddy</key>\\n\\t<data>\\n\\t\";\n    objectChanges = \"<relationship fault: 0x1651f9a0 'objectChanges'>\";\n    timestamp = \"17:16:23 +0000\";\n    type = 200;\n    uniqueIdentifier = \"83664AB6-F3FE-4454-B794-12858EB3215C-501-00000110A14995E1\";\n})"
)  <<<  __62-[CDEEventIntegrator storeModificationEventIDsForIntegration:]_block_invoke
18:16:32.550   Checking which events can be integrated                       <<<  -[CDEEventIntegrator integrableEventIDsFromEventIDs:informativeErrorCodes:]
18:16:32.554   Determining integrable events                                 <<<  -[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]
18:16:39.046   Checking store: 826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:39.047   Revision range: store id: 826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3
revision: 20
global count: 32 store id: 826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3
revision: 21
global count: 33  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:39.098   Checking store: 0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:39.099   Revision range: store id: 0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA
revision: 15
global count: 32 store id: 0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA
revision: 15
global count: 33  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:39.131   Checking if ready for integration                             <<<  -[CDEEventIntegrator integrationIsNeededForEventIDs:]
18:16:39.254   Beginning integration                                         <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.256   Integrating entity: DMBuddy                                   <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.267   Integrating entity: DMCertificate                             <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.287   Integrating entity: DMDiveLogEntry                            <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.309   Number of objects remaining to integrate for this entity: 0   <<<  __46-[CDEEventIntegrator integrateEventIDs:error:]_block_invoke
18:16:39.431   Integrating entity: DMDiver                                   <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.555   Integrating entity: DMEquipment                               <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.603   Integrating entity: DMPhoto                                   <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.672   Integrating entity: DMPlace                                   <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.765   Integrating entity: DMTagValue                                <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.784   Integrating entity: DMTankData                                <<<  -[CDEEventIntegrator integrateEventIDs:error:]
18:16:39.851   Repairing context after integrating changes                   <<<  -[CDEEventIntegrator repair:]
18:16:39.856   Committing merge changes to store                             <<<  -[CDEEventIntegrator commit:]
18:16:39.863   Storing pre-save changes from updated objects                 <<<  -[CDESaveMonitor storePreSaveChangesFromUpdatedObjects:]
18:16:40.045   Transferring data files from event store to cloud             <<<  -[CDECloudManager exportDataFilesWithProgress:]
18:16:40.094   Transferring baseline from event store to cloud               <<<  -[CDECloudManager exportNewLocalBaselineWithProgress:]
18:16:40.176   Transferring events from event store to cloud                 <<<  -[CDECloudManager exportNewLocalNonBaselineEventsWithProgress:]
18:16:40.322   Migrating events out to files                                 <<<  -[CDEEventMigrator migrateStoreModificationEventWithObjectID:toTemporaryFilesWithCompletion:]
18:16:40.369   Exporting files for entity: DMBuddy                           <<<  -[CDEEventExport main]
18:16:40.382   Exporting files for entity: DMCertificate                     <<<  -[CDEEventExport main]
18:16:40.394   Exporting files for entity: DMDiveLogEntry                    <<<  -[CDEEventExport main]
18:16:40.406   Exporting files for entity: DMDiver                           <<<  -[CDEEventExport main]
18:16:40.414   Exporting files for entity: DMEquipment                       <<<  -[CDEEventExport main]
18:16:40.423   Exporting files for entity: DMPhoto                           <<<  -[CDEEventExport main]
18:16:40.431   Exporting files for entity: DMPlace                           <<<  -[CDEEventExport main]
18:16:40.441   Exporting files for entity: DMTagValue                        <<<  -[CDEEventExport main]
18:16:40.451   Exporting files for entity: DMTankData                        <<<  -[CDEEventExport main]
18:16:40.485   Uploading files to remote path: (
    "/DemoAppMainStore/events/34_0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA_16.cdeevent"
)  <<<  __73-[CDECloudManager transferFilesInTransitCacheToRemoteDirectory:progress:]_block_invoke_3
18:16:40.487   Uploading from paths (
    "/var/mobile/Containers/Data/Application/3EA6BB44-7135-4C5D-91D3-D36878005B1C/Library/Application Support/ch.appzoo.DemoApp/com.mentalfaculty.ensembles.eventdata/transitcache/DemoAppMainStore/upload/34_0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA_16.cdeevent"
) to paths (
    "/DemoAppMainStore/events/34_0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA_16.cdeevent"
)  <<<  -[CDECloudKitFileSystem uploadLocalFiles:toPaths:completion:]
18:16:42.525   Removing outdated files                                       <<<  -[CDECloudManager removeOutdatedRemoteFilesWithCompletion:]
18:16:42.607   Removing cloud files:                                         <<<  -[CDECloudManager removeOutdatedRemoteFilesWithCompletion:]
18:16:42.625   Removing items at paths: (
)                                  <<<  -[CDECloudKitFileSystem removeItemsAtPaths:completion:]
18:16:42.626   Retrieving records for paths: (
)                             <<<  -[CDECloudKitFileSystem fetchRecordsAtPaths:completion:]
18:16:42.628   Fetched records for removal: (
)                              <<<  __55-[CDECloudKitFileSystem removeItemsAtPaths:completion:]_block_invoke
18:16:42.630   Removing items with recordIDs: (
)                            <<<  -[CDECloudKitFileSystem removeItemsWithRecordIDs:completion:]
18:16:42.651   Completing Merge                                              <<<  __58-[CDEPersistentStoreEnsemble mergeWithOptions:completion:]_block_invoke.694



18:16:48.068   Enqueuing merge                                               <<<  -[CDEPersistentStoreEnsemble mergeWithOptions:completion:]
18:16:48.082   Beginning merge                                               <<<  __47-[CDEPersistentStoreEnsemble newMergeSetupStep]_block_invoke
18:16:48.096   Priming CloudKit cache                                        <<<  -[CDECloudKitFileSystem primeForActivityWithCompletion:]
18:16:48.097   Beginning change processing for CloudKit.                     <<<  -[CDECloudKitFileSystem primeForActivityWithCompletion:]

18:16:48.464   Processed cloudkit change (insert/update): /DemoAppMainStore/events/34_0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA_16.cdeevent  <<<  __56-[CDECloudKitFileSystem primeForActivityWithCompletion:]_block_invoke
18:16:48.474   Processed cloudkit change (insert/update): /DemoAppMainStore/events/35_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_22.cdeevent  <<<  __56-[CDECloudKitFileSystem primeForActivityWithCompletion:]_block_invoke
18:16:48.477   Completing CloudKit fetch record changes                      <<<  __56-[CDECloudKitFileSystem primeForActivityWithCompletion:]_block_invoke.311
18:16:48.489   Checking identity in cloud system                             <<<  -[CDEPersistentStoreEnsemble checkCloudFileSystemIdentityWithCompletion:]
18:16:48.884   Passed identity check with identity: <CKRecordID: 0x1660a840; _7fd2f6a37e22282e02a1d8fb52ba2d8e:(_defaultZone:__defaultOwner__)>  <<<  __73-[CDEPersistentStoreEnsemble checkCloudFileSystemIdentityWithCompletion:]_block_invoke
18:16:48.889   Checking registration info                                    <<<  -[CDEPersistentStoreEnsemble checkStoreRegistrationInCloudWithCompletion:]
18:16:48.890   Checking existence of registration info                       <<<  -[CDECloudManager checkExistenceOfRegistrationInfoForStoreWithIdentifier:completion:]
18:16:48.891   Checking existence of file: /DemoAppMainStore/stores/0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA  <<<  -[CDECloudKitFileSystem fileExistsAtPath:completion:]
18:16:48.892   Retrieving records for paths: (
    "/DemoAppMainStore/stores/0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA"
)  <<<  -[CDECloudKitFileSystem fetchRecordsAtPaths:completion:]
18:16:48.893   File exists. Is dir? 0                                        <<<  __53-[CDECloudKitFileSystem fileExistsAtPath:completion:]_block_invoke
18:16:48.907 Localizable string "(A Document Being Saved By %@)" not found in strings table "Document" of bundle CFBundle 0x166429d0 </System/Library/Frameworks/Foundation.framework> (not loaded).
18:16:48.942   Getting contents of directory at path: /DemoAppMainStore/baselines  <<<  -[CDECloudKitFileSystem contentsOfDirectoryAtPath:completion:]
18:16:48.944   Getting contents of directory at path: /DemoAppMainStore/events  <<<  -[CDECloudKitFileSystem contentsOfDirectoryAtPath:completion:]
18:16:48.947   Getting contents of directory at path: /DemoAppMainStore/data  <<<  -[CDECloudKitFileSystem contentsOfDirectoryAtPath:completion:]
18:16:48.954   Removing incomplete remote file sets                          <<<  -[CDECloudManager removeLocallyProducedIncompleteRemoteFileSets:]
18:16:49.016   Transferring new data files from cloud to event store         <<<  -[CDECloudManager importNewDataFilesWithProgress:]
18:16:49.028   Transferring new baselines from cloud to event store          <<<  -[CDECloudManager importNewBaselineEventsWithProgress:]
18:16:49.057   Consolidating baselines                                       <<<  -[CDEBaselineConsolidator consolidateBaselineWithCompletion:]
18:16:49.068   Found baselines with unique ids: (
    "848B3010-D3D0-4928-BFA9-249D2CE617A0-777-000002E2704C7408"
)  <<<  __61-[CDEBaselineConsolidator consolidateBaselineWithCompletion:]_block_invoke
18:16:49.069   Baselines remaining that need merging: 1                      <<<  __61-[CDEBaselineConsolidator consolidateBaselineWithCompletion:]_block_invoke
18:16:49.071   Finishing baseline consolidation                              <<<  __61-[CDEBaselineConsolidator consolidateBaselineWithCompletion:]_block_invoke_2
18:16:49.075   Transferring new events from cloud to event store             <<<  -[CDECloudManager importNewRemoteNonBaselineEventsWithProgress:]
18:16:49.150   Downloading files to transit cache: (
    "/DemoAppMainStore/events/35_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_22.cdeevent"
)  <<<  __83-[CDECloudManager downloadFiles:fromRemoteDirectory:batchCompletionBlock:progress:]_block_invoke_2
18:16:49.153   Downloading from paths (
    "/DemoAppMainStore/events/35_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_22.cdeevent"
) to path (
    "/var/mobile/Containers/Data/Application/3EA6BB44-7135-4C5D-91D3-D36878005B1C/Library/Application Support/ch.appzoo.DemoApp/com.mentalfaculty.ensembles.eventdata/transitcache/DemoAppMainStore/download/35_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_22.cdeevent"
)  <<<  -[CDECloudKitFileSystem downloadFromPaths:toLocalFiles:completion:]
18:16:50.214   Migrating event in to event store from files: (
    "35_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_22.cdeevent"
)  <<<  __84-[CDECloudManager migrateNewEventsWhichAreBaselines:fromTransitCacheWithCompletion:]_block_invoke.292
18:16:50.215   Migrating events in from files                                <<<  -[CDEEventMigrator migrateEventInFromFileURLs:completion:]
18:16:50.218   Migrating file events to event store                          <<<  -[CDEEventImport main]
18:16:50.219   Importing file at URL: file:///var/mobile/Containers/Data/Application/3EA6BB44-7135-4C5D-91D3-D36878005B1C/Library/Application%20Support/ch.appzoo.DemoApp/com.mentalfaculty.ensembles.eventdata/transitcache/DemoAppMainStore/download/35_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_22.cdeevent  <<<  __22-[CDEEventImport main]_block_invoke.22
18:16:50.456   Determining events to include in integration                  <<<  -[CDEEventIntegrator storeModificationEventIDsForIntegration:]
18:16:50.600   Including these events in the integration: (
    "<CDEStoreModificationEvent: 0x178b45e0> (entity: CDEStoreModificationEvent; id: 0x165342e0 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEStoreModificationEvent/p40> ; data: {\n    eventRevision = \"0x178a4cc0 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEEventRevision/p77>\";\n    eventRevisionsOfOtherStores =     (\n        \"0x178a4cd0 <x-coredata://7EC8021F-B83B-4A27-B9B9-D1645A533448/CDEEventRevision/p78>\"\n    );\n    globalCount = 35;\n    modelVersion = \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\n<!DOCTYPE plist PUBLIC \\\"-//Apple//DTD PLIST 1.0//EN\\\" \\\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\\\">\\n<plist version=\\\"1.0\\\">\\n<dict>\\n\\t<key>DMBuddy</key>\\n\\t<data>\\n\\t\";\n    objectChanges = \"<relationship fault: 0x1651e8d0 'objectChanges'>\";\n    timestamp = \"17:16:45 +0000\";\n    type = 300;\n    uniqueIdentifier = \"3F19C4EE-816D-425F-99BC-BE991EEE1476-501-00000110C03D4133\";\n})"
)  <<<  __62-[CDEEventIntegrator storeModificationEventIDsForIntegration:]_block_invoke
18:16:50.601   Checking which events can be integrated                       <<<  -[CDEEventIntegrator integrableEventIDsFromEventIDs:informativeErrorCodes:]
18:16:50.603   Determining integrable events                                 <<<  -[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]
18:16:54.843   Checking store: 826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:54.845   Revision range: store id: 826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3
revision: 22
global count: 35 store id: 826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3
revision: 22
global count: 35  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:54.872   Checking store: 0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:54.874   Revision range: store id: 0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA
revision: 16
global count: 35 store id: 0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA
revision: 16
global count: 35  <<<  __71-[CDERevisionManager integrableEventsFromEvents:informativeErrorCodes:]_block_invoke
18:16:54.903   Checking if ready for integration                             <<<  -[CDEEventIntegrator integrationIsNeededForEventIDs:]
18:16:54.975   Transferring data files from event store to cloud             <<<  -[CDECloudManager exportDataFilesWithProgress:]
18:16:54.996   Transferring baseline from event store to cloud               <<<  -[CDECloudManager exportNewLocalBaselineWithProgress:]
18:16:55.058   Transferring events from event store to cloud                 <<<  -[CDECloudManager exportNewLocalNonBaselineEventsWithProgress:]
18:16:55.163   Removing outdated files                                       <<<  -[CDECloudManager removeOutdatedRemoteFilesWithCompletion:]
18:16:55.249   Removing cloud files:                                         <<<  -[CDECloudManager removeOutdatedRemoteFilesWithCompletion:]
18:16:55.269   Removing items at paths: (
)                                  <<<  -[CDECloudKitFileSystem removeItemsAtPaths:completion:]
18:16:55.270   Retrieving records for paths: (
)                             <<<  -[CDECloudKitFileSystem fetchRecordsAtPaths:completion:]
18:16:55.273   Fetched records for removal: (
)                              <<<  __55-[CDECloudKitFileSystem removeItemsAtPaths:completion:]_block_invoke
18:16:55.274   Removing items with recordIDs: (
)                            <<<  -[CDECloudKitFileSystem removeItemsWithRecordIDs:completion:]
18:16:55.298   Completing Merge                                              <<<  __58-[CDEPersistentStoreEnsemble mergeWithOptions:completion:]_block_invoke.694

...and here are the push notifications:

IPOD TOUCH
18:16:28.199 | iCloudSyncActivity | Thread 16 | did receive remote notification, userInfo = '{
    aps =     {
        "content-available" = 1;
        sound = "";
    };
    ck =     {
        ce = 2;
        cid = "iCloud.com.example.app";
        nid = "cc0f33fc-0488-4abb-b9aa-2bfd7c8db88b";
        qry =         {
            dbs = 1;
            fo = 1;
            rid = "CDEFileSystemNode_/DiveMateMainStore/events/33_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_21.cdeevent";
            sid = CDEFileAddedSubscription;
            zid = "com.mentalfaculty.ensembles.zone.schema2";
            zoid = "_7fd2f6a37e22282e02a1d8fb52ba2d8e";
        };
    };
}'

IPAD:
18:16:42.258 | iCloudSyncActivity | Thread 15 | did receive remote notification, userInfo = '{
    aps =     {
        "content-available" = 1;
        sound = "";
    };
    ck =     {
        ce = 2;
        cid = "iCloud.com.example.app";
        nid = "2bb1a2f0-5dbb-47b7-b6e1-1e6de9afdac9";
        qry =         {
            dbs = 1;
            fo = 1;
            rid = "CDEFileSystemNode_/DiveMateMainStore/events/34_0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA_16.cdeevent";
            sid = CDEFileAddedSubscription;
            zid = "com.mentalfaculty.ensembles.zone.schema2";
            zoid = "_7fd2f6a37e22282e02a1d8fb52ba2d8e";
        };
    };
}'

IPOD TOUCH
[260     ] 18:16:48.064 | iCloudSyncActivity | Thread 16 | did receive remote notification, userInfo = '{
    aps =     {
        "content-available" = 1;
        sound = "";
    };
    ck =     {
        ce = 2;
        cid = "iCloud.com.example.app";
        nid = "4ee5383d-9a94-4596-99f2-18ae7da6e0ca";
        qry =         {
            dbs = 1;
            fo = 1;
            rid = "CDEFileSystemNode_/DiveMateMainStore/events/35_826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3_22.cdeevent";
            sid = CDEFileAddedSubscription;
            zid = "com.mentalfaculty.ensembles.zone.schema2";
            zoid = "_7fd2f6a37e22282e02a1d8fb52ba2d8e";
        };
    };
}'

What seems odd to me is that the Ensembles trace refers to 2 stores:
-one with id 826D4BD2-2ED2-4C3B-9A89-22E3D910EC55-476-000000FAF9F774C3
-one with id 0B96EB62-03B1-414F-BBA5-3FCBDD2E9CD4-777-000002E26205C2DA

For reference, this is how I setup Ensembles:

_ensemble = [[CDEPersistentStoreEnsemble alloc] initWithEnsembleIdentifier:DM_ENSEMBLE_IDENTIFIER
                                                        persistentStoreURL:storeURL
                                                     managedObjectModelURL:[self _getManagedObjectModelURL]
                                                           cloudFileSystem:_iCloudFileSystem];

Any help/pointers in the right direction are greatly appreciated.

Upvotes: 0

Views: 171

Answers (1)

Drew McCormack
Drew McCormack

Reputation: 3592

This is expected behavior, and the last merge should be very fast. If you find it too much, you can easily choose to throttle back your merges that are triggered by push notifications. Eg. If a push comes in within a minute of doing a merge, you could choose to ignore it.

The 3 merges per change are not no-ops. They are doing important accounting to ensure that devices all end up with the same data.

Think of Ensembles like Git. Internally, that is basically what it is. Now, you make a change on one device, which triggers a new commit (S1_D1) on that device. Then you do a merge to push the data to the cloud.

The second device now merges to get that data due to a push notification, and creates a commit for that (M1_D2). This may or may not include conflict resolutions, but it is important to the concurrency system. It is the equivalent in Git of merging two branches, and you have to have a new commit to represent that in the history.

The merge (M1_D2) is pushed to the cloud, and now the original device sees a new commit, and has to do a merge operation to import it, though it doesn't produce any new commits itself.

So a single save should require a merge on the original device, a merge on the other device, and another merge on the original device, in order to complete fully. That is how it works in a system like Git, and also in Ensembles.

Note that although 3 merge operations are needed, you have complete control over when they happen. You can delay them as long as you like, or ignore certain pushes as I mentioned. The system is smart enough to figure it all out when you do eventually merge (just like Git can).

Upvotes: 3

Related Questions