Batch backup exports.

This commit is contained in:
Matthew Chen 2018-11-30 17:17:56 -05:00
parent 57205facbc
commit 855cba3c41
2 changed files with 51 additions and 4 deletions

View File

@ -81,6 +81,18 @@ NS_ASSUME_NONNULL_BEGIN
actionBlock:^{
[AppEnvironment.shared.backupLazyRestore runIfNecessary];
}]];
[items addObject:[OWSTableItem itemWithTitle:@"Upload 100 CK records"
actionBlock:^{
[DebugUIBackup uploadCKBatch:100];
}]];
[items addObject:[OWSTableItem itemWithTitle:@"Upload 1,000 CK records"
actionBlock:^{
[DebugUIBackup uploadCKBatch:1000];
}]];
[items addObject:[OWSTableItem itemWithTitle:@"Upload 10,000 CK records"
actionBlock:^{
[DebugUIBackup uploadCKBatch:10000];
}]];
return [OWSTableSection sectionWithTitle:self.name items:items];
}
@ -221,6 +233,26 @@ NS_ASSUME_NONNULL_BEGIN
[self.backup logBackupMetadataCache:OWSPrimaryStorage.sharedManager.newDatabaseConnection];
}
+ (void)uploadCKBatch:(NSUInteger)count
{
NSMutableArray<CKRecord *> *records = [NSMutableArray new];
for (NSUInteger i = 0; i < count; i++) {
NSData *_Nullable data = [Randomness generateRandomBytes:32];
OWSAssertDebug(data);
NSString *filePath = [OWSFileSystem temporaryFilePathWithFileExtension:@"pdf"];
BOOL success = [data writeToFile:filePath atomically:YES];
OWSAssertDebug(success);
NSString *recipientId = self.tsAccountManager.localNumber;
NSString *recordName = [OWSBackupAPI recordNameForTestFileWithRecipientId:recipientId];
CKRecord *record = [OWSBackupAPI recordForFileUrl:[NSURL fileURLWithPath:filePath] recordName:recordName];
[records addObject:record];
}
[[OWSBackupAPI saveRecordsToCloudObjcWithRecords:records].thenInBackground(^{
OWSLogVerbose(@"success.");
}) retainUntilComplete];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -134,8 +134,23 @@ import PromiseKit
}
public class func saveRecordsToCloud(records: [CKRecord]) -> Promise<Void> {
return saveRecordsToCloud(records: records,
remainingRetries: maxRetries)
var remainder = records
var promise = Promise.value(())
// CloudKit's internal limit is 400, but I haven't found a constant for this.
let kMaxBatchSize = 100
while remainder.count > 0 {
let batch = Array(remainder[0..<kMaxBatchSize])
remainder = Array(remainder[kMaxBatchSize..<remainder.count])
promise = promise.then(on: DispatchQueue.global()) { _ in
return saveRecordsToCloud(records: batch,
remainingRetries: maxRetries)
}.then(on: DispatchQueue.global()) { _ -> Promise<Void> in
Logger.verbose("Saved batch: \(batch.count)")
return Promise.value(())
}
}
return promise
}
private class func saveRecordsToCloud(records: [CKRecord],
@ -144,7 +159,7 @@ import PromiseKit
let recordNames = records.map { (record) in
return record.recordID.recordName
}
Logger.verbose("recordNames \(recordNames)")
Logger.verbose("recordNames[\(recordNames.count)] \(recordNames[0..<10])...")
return Promise { resolver in
let saveOperation = CKModifyRecordsOperation(recordsToSave: records, recordIDsToDelete: nil)
@ -173,7 +188,7 @@ import PromiseKit
let outcome = outcomeForCloudKitError(error: error,
remainingRetries: remainingRetries,
label: "Save Record")
label: "Save Records[\(recordNames.count)]")
switch outcome {
case .success:
resolver.fulfill(())