mirror of https://github.com/oxen-io/session-ios
Merge branch 'charlesmchen/incrementalBackup8'
commit
972cbaebfb
@ -1 +1 @@
|
||||
Subproject commit 1d47ca77ea929a2fd76b2b3410487b61f18f5b54
|
||||
Subproject commit 10be6cb3689bd1815ffcecc2f9500b2b55f60962
|
@ -0,0 +1,92 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import PromiseKit
|
||||
import SignalServiceKit
|
||||
|
||||
@objc
|
||||
public class OWSBackupLazyRestoreJob: NSObject {
|
||||
|
||||
let primaryStorage: OWSPrimaryStorage
|
||||
|
||||
private var jobTempDirPath: String?
|
||||
|
||||
deinit {
|
||||
if let jobTempDirPath = self.jobTempDirPath {
|
||||
DispatchQueue.global().async {
|
||||
OWSFileSystem.deleteFile(jobTempDirPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public class func runAsync() {
|
||||
OWSBackupLazyRestoreJob().runAsync()
|
||||
}
|
||||
|
||||
public override init() {
|
||||
self.primaryStorage = OWSPrimaryStorage.shared()
|
||||
}
|
||||
|
||||
private func runAsync() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
DispatchQueue.global().async {
|
||||
self.restoreAttachments()
|
||||
}
|
||||
}
|
||||
|
||||
private func restoreAttachments() {
|
||||
let temporaryDirectory = NSTemporaryDirectory()
|
||||
let jobTempDirPath = (temporaryDirectory as NSString).appendingPathComponent(NSUUID().uuidString)
|
||||
|
||||
guard OWSFileSystem.ensureDirectoryExists(jobTempDirPath) else {
|
||||
Logger.error("\(logTag) could not create temp directory.")
|
||||
return
|
||||
}
|
||||
|
||||
self.jobTempDirPath = jobTempDirPath
|
||||
|
||||
let backupIO = OWSBackupIO(jobTempDirPath: jobTempDirPath)
|
||||
|
||||
let attachmentIds = OWSBackup.shared().attachmentIdsForLazyRestore()
|
||||
guard attachmentIds.count > 0 else {
|
||||
Logger.info("\(logTag) No attachments need lazy restore.")
|
||||
return
|
||||
}
|
||||
Logger.info("\(logTag) Lazy restoring \(attachmentIds.count) attachments.")
|
||||
self.tryToRestoreNextAttachment(attachmentIds: attachmentIds, backupIO: backupIO)
|
||||
}
|
||||
|
||||
private func tryToRestoreNextAttachment(attachmentIds: [String], backupIO: OWSBackupIO) {
|
||||
var attachmentIdsCopy = attachmentIds
|
||||
guard let attachmentId = attachmentIdsCopy.last else {
|
||||
// This job is done.
|
||||
Logger.verbose("\(logTag) job is done.")
|
||||
return
|
||||
}
|
||||
attachmentIdsCopy.removeLast()
|
||||
guard let attachment = TSAttachmentStream.fetch(uniqueId: attachmentId) else {
|
||||
Logger.warn("\(logTag) could not load attachment.")
|
||||
// Not necessarily an error.
|
||||
// The attachment might have been deleted since the job began.
|
||||
// Continue trying to restore the other attachments.
|
||||
tryToRestoreNextAttachment(attachmentIds: attachmentIds, backupIO: backupIO)
|
||||
return
|
||||
}
|
||||
OWSBackup.shared().lazyRestoreAttachment(attachment,
|
||||
backupIO: backupIO,
|
||||
completion: { (success) in
|
||||
if success {
|
||||
Logger.info("\(self.logTag) restored attachment.")
|
||||
} else {
|
||||
Logger.warn("\(self.logTag) could not restore attachment.")
|
||||
}
|
||||
// Continue trying to restore the other attachments.
|
||||
self.tryToRestoreNextAttachment(attachmentIds: attachmentIdsCopy, backupIO: backupIO)
|
||||
})
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSYapDatabaseObject.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
// We store metadata for known backup fragments (i.e. CloudKit record) in
|
||||
// the database. We might learn about them from:
|
||||
//
|
||||
// * Past backup exports.
|
||||
// * An import downloading and parsing the manifest of the last complete backup.
|
||||
//
|
||||
// Storing this data in the database provides continuity.
|
||||
//
|
||||
// * Backup exports can reuse fragments from previous Backup exports even if they
|
||||
// don't complete (i.e. backup export resume).
|
||||
// * Backup exports can reuse fragments from the backup import, if any.
|
||||
@interface OWSBackupFragment : TSYapDatabaseObject
|
||||
|
||||
@property (nonatomic) NSString *recordName;
|
||||
|
||||
@property (nonatomic) NSData *encryptionKey;
|
||||
|
||||
// This property is only set for certain types of manifest item,
|
||||
// namely attachments where we need to know where the attachment's
|
||||
// file should reside relative to the attachments folder.
|
||||
@property (nonatomic, nullable) NSString *relativeFilePath;
|
||||
|
||||
// This property is only set for attachments.
|
||||
@property (nonatomic, nullable) NSString *attachmentId;
|
||||
|
||||
// This property is only set if the manifest item is downloaded.
|
||||
@property (nonatomic, nullable) NSString *downloadFilePath;
|
||||
|
||||
// This property is only set if the manifest item is compressed.
|
||||
@property (nonatomic, nullable) NSNumber *uncompressedDataLength;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBackupFragment.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@implementation OWSBackupFragment
|
||||
|
||||
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(self.recordName.length > 0);
|
||||
|
||||
if (!self.uniqueId) {
|
||||
self.uniqueId = self.recordName;
|
||||
}
|
||||
[super saveWithTransaction:transaction];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
Loading…
Reference in New Issue