2014-06-11 11 views
5

Sprechen die offiziellen Dokumente irgendwo über die Konsistenz von CloudKit? Nach meinen Tests scheint es schließlich, konsequent zu sein - eine Aufzeichnung sofort nach dem Lesen des Schreiben es funktionieren könnte und möglicherweise nicht (leer Ergebnisse Rückkehr):Ist CloudKit stark konsistent oder sogar konsistent?

CKDatabase *database = [[CKContainer defaultContainer] publicCloudDatabase]; 
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Foo"]; 

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); 
[database saveRecord:record completionHandler:^(CKRecord *record, NSError *error) { 
    CKQuery *query = [[CKQuery alloc] initWithRecordType:@"Foo" predicate:[NSPredicate predicateWithFormat:@"TRUEPREDICATE"]]; 
    [database performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) { 
     XCTAssertEqualObjects(results, @[], @"Freshly written object not returned by query."); // succeeds 
     dispatch_semaphore_signal(semaphore); 
    }]; 
}]; 

dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

Gibt es eine Möglichkeit, eine stark konsistente Lese zu zwingen, die alle widerspiegeln würde vorherige Updates?

+0

Ich merke das gleiche in meinen Tests. Ich speichere eine Aufzeichnung und warte darauf, dass sie erfolgreich abgeschlossen wird. Wenn ich dann eine Abfrage für alle Datensätze durchführe, wird mein neuer Datensatz nicht zurückgegeben. Haben Sie Informationen darüber gefunden, dass CloudKit letztendlich konsistent ist? –

+0

Mein Anwendungsfall war glücklicherweise sehr einfach, also löste ich das Problem mit einer Art Cache im Datenspeicher-Layer: Wenn ein Objekt in den Datenspeicher eingefügt wird, wird es für kurze Zeit in iCloud _and_ auf dem Client gespeichert. Und wenn der Datenspeicher-Layer abgefragt wird, fügt er die lebenden Cache-Datensätze zur Ergebnismenge hinzu. Dumm, aber funktioniert. – zoul

+1

@zoul jemals einen besseren Weg finden, damit umzugehen? Der letzte Teil des Inline-Kommentars in CKModifyRecordsOperation.h für modifyRecordsCompletionBlock schlägt vor, dass dies das entworfene Verhalten ist: "** Dieser Aufruf erfolgt, sobald der Server alle Datensatzänderungen gesehen hat und möglicherweise aufgerufen wird, während der Server die Seite verarbeitet Auswirkungen dieser Änderungen. ** " – George

Antwort

0

Meine einzige Erfahrung mit dem Begriff "Eventual Consistency" ist die Verwendung von CouchDB, die schließlich konsistent ist. CloudKit unterscheidet sich sehr von CouchDB, da CouchDB die Replikation verteilter Datenbanken ermöglicht, während CloudKit nur "Dienste zur Verwaltung der Übertragung von Daten zu und von iCloud-Servern" bereitstellt - es handelt sich lediglich um einen Transportmechanismus.

Ich bin mir ziemlich sicher, dass der Transportmechanismus letztendlich nicht konsistent ist - er speichert und ruft direkt vom CloudKit Server ab.

Da CloudKit nur ein Transportmechanismus ist, müssen Sie Ihren eigenen lokalen Cache/Datenbank verwalten. Ihre lokale Datenbank wird möglicherweise als konsistent betrachtet, da sie zwischen den Synchronisierungen nicht konsistent ist und erst konsistent wird, wenn Sie sie schließlich mit CloudKit synchronisieren.

Jetzt sagen Sie, dass Sie in Ihren Tests speichern und dann versuchen, einen Datensatz abzurufen. Aber ich merke in Ihrem Code, dass Sie nicht nach Fehlern in der Sicherungsoperation suchen. Also, gibt es vielleicht einen Fehler während der Sicherung, die Sie vermissen?

+0

Ich weiß nichts über die iCloud-Infrastruktur von Apple, aber ich vermute, dass hinter einem Lastausgleichsschema viele verschiedene iCloud-Server laufen.Es erscheint also durchaus möglich, dass ein Aufruf zum Speichern eines Datensatzes an eine Serverinstanz weitergeleitet wird, während ein nachfolgender Aufruf an eine andere Instanz weitergeleitet wird. Je nachdem, wie gut iCloud diese Instanzen synchronisiert hält, kann es durchaus vernünftig sein, hier ein Konsistenzmodell zu haben. –

7

Es ist ein wenig von beiden: CloudKit ist stark konsistent, wenn Sie einen Datensatz nach Bezeichner abrufen, aber schließlich konsistent, wenn Sie einen Datensatz mit einer Abfrage abrufen.

Wenn eine CKModifyRecordsOperation erfolgreich zurückgegeben wird, kann der Datensatz sofort mit seiner Kennung abgerufen werden.

Es dauert jedoch einige Zeit, bis der Server die Werte des Datensatzes überprüft und seine Suchindizes aktualisiert und verteilt. Bis diese Indizierung abgeschlossen ist, wird der Datensatz in keiner Abfrage angezeigt.