object:(ASIPithosObject *)object
localFilePath:(NSString *)filePath;
- (void)requestFailed:(ASIPithosRequest *)request;
+
+- (void)increaseSyncOperationCount;
+- (void)decreaseSyncOperationCount;
+
@end
@implementation PithosSyncDaemon
-@synthesize blockHash, blockSize, lastModified, remoteObjects, storedLocalObjectStates;
+@synthesize blockHash, blockSize, lastModified, lastCompletedSync, remoteObjects, storedLocalObjectStates;
@synthesize pithosStateFilePath, tempDownloadsDirPath;
#pragma mark -
[storedLocalObjectStates release];
[remoteObjects release];
[objects release];
+ [lastCompletedSync release];
[lastModified release];
[blockHash release];
[containerName release];
[data writeToFile:self.pithosStateFilePath atomically:YES];
}
+- (void)increaseSyncOperationCount {
+ @synchronized(self) {
+ syncOperationCount++;
+ }
+}
+
+- (void)decreaseSyncOperationCount {
+ @synchronized(self) {
+ syncOperationCount--;
+ if (!syncOperationCount && !syncIncomplete) {
+ self.lastCompletedSync = [NSDate date];
+ [activityFacility startAndEndActivityWithType:PithosActivityOther
+ message:[NSString stringWithFormat:@"Sync: Completed %@", lastCompletedSync]];
+ }
+ }
+}
+
- (void)sync {
@synchronized(self) {
if (syncOperationCount) {
// The first operation is the server listing
syncOperationCount = 1;
newSyncRequested = NO;
+ syncIncomplete = NO;
}
}
message:@"Sync: Getting server listing"];
containerRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
activity, @"activity",
+ @"Sync: Getting server listing (stopped)", @"stoppedActivityMessage",
+ @"Sync: Getting server listing (failed)", @"failedActivityMessage",
+ @"Sync: Getting server listing (finished)", @"finishedActivityMessage",
+ [NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
nil];
-// [[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
[queue addOperation:[PithosUtilities prepareRequest:containerRequest priority:NSOperationQueuePriorityVeryHigh]];
}
message:[NSString stringWithFormat:@"Sync: Downloading '%@' (100%%)", object.name]];
} else if (storedState.tmpDownloadFile == nil) {
// Create new local object
- @synchronized(self) {
- syncOperationCount++;
- }
+ [self increaseSyncOperationCount];
__block ASIPithosObjectRequest *objectRequest = [PithosUtilities objectBlockDataRequestWithContainerName:containerName
object:object
blockIndex:0
[NSString stringWithFormat:@"Sync: Downloading '%@' (stopped)", object.name], @"stoppedActivityMessage",
[NSString stringWithFormat:@"Sync: Downloading '%@' (failed)", object.name], @"failedActivityMessage",
[NSString stringWithFormat:@"Sync: Downloading '%@' (100%%)", object.name], @"finishedActivityMessage",
- [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
+ [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
nil];
[objectRequest setBytesReceivedBlock:^(unsigned long long size, unsigned long long total){
totalBytes:activity.totalBytes
currentBytes:(activity.currentBytes + size)];
}];
-// [[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
} else {
// Resume local object download
- @synchronized(self) {
- syncOperationCount++;
- }
+ [self increaseSyncOperationCount];
ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest objectHashmapRequestWithContainerName:containerName
objectName:object.name];
objectRequest.delegate = self;
[NSString stringWithFormat:@"Sync: Downloading '%@' (stopped)", object.name], @"stoppedActivityMessage",
[NSString stringWithFormat:@"Sync: Downloading '%@' (failed)", object.name], @"failedActivityMessage",
[NSString stringWithFormat:@"Sync: Downloading '%@' (100%%)", object.name], @"finishedActivityMessage",
- [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
+ [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
nil];
-// [[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
}
}
-(void)updateServerStateWithCurrentState:(PithosLocalObjectState *)currentState
object:(ASIPithosObject *)object
localFilePath:(NSString *)filePath {
+ [self increaseSyncOperationCount];
if (currentState.isDirectory) {
// Create remote directory object
- @synchronized(self) {
- syncOperationCount++;
- }
ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest writeObjectDataRequestWithContainerName:containerName
objectName:object.name
eTag:nil
[NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
nil];
-// [[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
[queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
} else if ([currentState.md5 isEqualToString:@" "] && [currentState.hashMapHash isEqualToString:@" "]) {
// Delete remote object
- @synchronized(self) {
- syncOperationCount++;
+ NSString *safeObjectName = [PithosUtilities safeObjectNameForContainerName:@"trash"
+ objectName:object.name];
+ if (safeObjectName) {
+ ASIPithosObjectRequest *objectRequest = [PithosUtilities moveObjectRequestWithContainerName:containerName
+ objectName:object.name
+ destinationContainerName:@"trash"
+ destinationObjectName:safeObjectName
+ checkIfExists:NO];
+ if (objectRequest) {
+ objectRequest.delegate = self;
+ objectRequest.didFinishSelector = @selector(moveObjectToTrashFinished:);
+ objectRequest.didFailSelector = @selector(requestFailed:);
+ PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDelete
+ message:[NSString stringWithFormat:@"Sync: Moving to trash '%@'", object.name]];
+ objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
+ object, @"pithosObject",
+ activity, @"activity",
+ [NSString stringWithFormat:@"Sync: Moving to trash '%@' (stopped)", object.name], @"stoppedActivityMessage",
+ [NSString stringWithFormat:@"Sync: Moving to trash '%@' (failed)", object.name], @"failedActivityMessage",
+ [NSString stringWithFormat:@"Sync: Moving to trash '%@' (finished)", object.name], @"finishedActivityMessage",
+ [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
+ [NSNumber numberWithUnsignedInteger:10], @"retries",
+ nil];
+ [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+ } else {
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
+ }
+ } else {
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
}
- ASIPithosObjectRequest *objectRequest = [ASIPithosObjectRequest deleteObjectRequestWithContainerName:containerName
- objectName:object.name];
- objectRequest.delegate = self;
- objectRequest.didFinishSelector = @selector(deleteObjectFinished:);
- objectRequest.didFailSelector = @selector(requestFailed:);
- PithosActivity *activity = [activityFacility startActivityWithType:PithosActivityDelete
- message:[NSString stringWithFormat:@"Sync: Deleting '%@'", object.name]];
- objectRequest.userInfo = [NSMutableDictionary dictionaryWithObjectsAndKeys:
- object, @"pithosObject",
- activity, @"activity",
- [NSString stringWithFormat:@"Sync: Deleting '%@' (stopped)", object.name], @"stoppedActivityMessage",
- [NSString stringWithFormat:@"Sync: Deleting '%@' (failed)", object.name], @"failedActivityMessage",
- [NSString stringWithFormat:@"Sync: Deleting '%@' (finished)", object.name], @"finishedActivityMessage",
- [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
- [NSNumber numberWithUnsignedInteger:10], @"retries",
- nil];
-// [[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
} else {
// Upload file to remote object
NSError *error = nil;
hashes:&hashes
sharingAccount:nil];
if (objectRequest) {
- @synchronized(self) {
- syncOperationCount++;
- }
objectRequest.delegate = self;
objectRequest.didFinishSelector = @selector(uploadObjectUsingHashMapFinished:);
objectRequest.didFailSelector = @selector(requestFailed:);
[NSString stringWithFormat:@"Sync: Uploading '%@' (stopped)", object.name], @"stoppedActivityMessage",
[NSString stringWithFormat:@"Sync: Uploading '%@' (failed)", object.name], @"failedActivityMessage",
[NSString stringWithFormat:@"Sync: Uploading '%@' (100%%)", object.name], @"finishedActivityMessage",
- [NSNumber numberWithInteger:NSOperationQueuePriorityHigh], @"priority",
+ [NSNumber numberWithInteger:NSOperationQueuePriorityNormal], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
nil]];
-// [[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:objectRequest priority:NSOperationQueuePriorityNormal]];
+ } else {
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
}
}
newContainerRequest.didFailSelector = @selector(listRequestFailed:);
newContainerRequest.userInfo = newContainerRequest.userInfo;
[(NSMutableDictionary *)newContainerRequest.userInfo setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
-// [[PithosUtilities prepareRequest:newContainerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:NSOperationQueuePriorityHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
return;
}
}
[activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"]
- withMessage:@"Sync: Getting server listing (finished)"];
+ withMessage:[containerRequest.userInfo objectForKey:@"finishedActivityMessage"]];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *containerDirectoryPath = [directoryPath stringByAppendingPathComponent:containerName];
NSError *error = nil;
}
}
@synchronized(self) {
- syncOperationCount--;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
if (retries > 0) {
ASIPithosContainerRequest *newContainerRequest = (ASIPithosContainerRequest *)[PithosUtilities copyRequest:containerRequest];
[(NSMutableDictionary *)(newContainerRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
-// [[PithosUtilities prepareRequest:newContainerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:NSOperationQueuePriorityHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
} else {
[activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"]
- withMessage:@"Sync: Getting server listing (failed)"];
+ withMessage:[containerRequest.userInfo objectForKey:@"failedActivityMessage"]];
@synchronized(self) {
// Since the server listing failed in all retries, the operation finished and the sync cycle is completeted unsuccesfully
syncOperationCount = 0;
- (void)listRequestFailed:(ASIPithosContainerRequest *)containerRequest {
if ([containerRequest isCancelled]) {
[activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"]
- withMessage:@"Sync: Getting server listing (stopped)"];
+ withMessage:[containerRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
[objects release];
objects = nil;
@synchronized(self) {
if (retries > 0) {
ASIPithosContainerRequest *newContainerRequest = (ASIPithosContainerRequest *)[PithosUtilities copyRequest:containerRequest];
[(NSMutableDictionary *)(newContainerRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
-// [[PithosUtilities prepareRequest:newContainerRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:NSOperationQueuePriorityVeryHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
} else {
[activityFacility endActivity:[containerRequest.userInfo objectForKey:@"activity"]
- withMessage:@"Sync: Getting server listing (failed)"];
+ withMessage:[containerRequest.userInfo objectForKey:@"failedActivityMessage"]];
[objects release];
objects = nil;
@synchronized(self) {
[activityFacility endActivity:activity
withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[activityFacility endActivity:activity
withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[activityFacility endActivity:activity
withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"]
withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[activityFacility endActivity:activity
withMessage:[objectRequest.userInfo objectForKey:@"failedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[self saveLocalState];
@synchronized(self) {
- syncOperationCount--;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"]
withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (!syncOperationCount)
[self sync];
}
totalBytes:activity.totalBytes
currentBytes:(activity.currentBytes + size)];
}];
-// [[PithosUtilities prepareRequest:newObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:NSOperationQueuePriorityHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
}
}
} else if (objectRequest.responseStatusCode == 412) {
[activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"]
withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"]
withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (!syncOperationCount)
[self sync];
}
totalBytes:activity.totalBytes
currentBytes:(activity.currentBytes + size)];
}];
-// [[PithosUtilities prepareRequest:newObjectRequest priority:NSOperationQueuePriorityHigh] startAsynchronous];
- [queue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:NSOperationQueuePriorityHigh]];
+ [queue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
}
} else {
[self requestFailed:objectRequest];
[activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"]
withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
}
}
-- (void)deleteObjectFinished:(ASIPithosObjectRequest *)objectRequest {
- NSLog(@"Sync::delete object finished: %@", objectRequest.url);
- if (objectRequest.responseStatusCode == 204) {
+- (void)moveObjectToTrashFinished:(ASIPithosObjectRequest *)objectRequest {
+ NSLog(@"Sync::move object to trash finished: %@", objectRequest.url);
+ if (objectRequest.responseStatusCode == 201) {
[storedLocalObjectStates removeObjectForKey:[[objectRequest.userInfo objectForKey:@"pithosObject"] name]];
[self saveLocalState];
[activityFacility endActivity:[objectRequest.userInfo objectForKey:@"activity"]
withMessage:[objectRequest.userInfo objectForKey:@"finishedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
totalBytes:totalBytes
currentBytes:totalBytes];
@synchronized(self) {
- syncOperationCount--;
+ [self decreaseSyncOperationCount];
if (newSyncRequested && !syncOperationCount)
[self sync];
}
[activityFacility endActivity:activity
withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (!syncOperationCount)
[self sync];
}
if (iteration == 0) {
NSLog(@"Sync::upload iteration limit reached: %@", objectRequest.url);
[activityFacility endActivity:activity
- withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
- @synchronized(self) {
- syncOperationCount--;
- }
+ withMessage:[objectRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
return;
}
NSLog(@"Sync::object is missing hashes: %@", objectRequest.url);
totalBytes:activity.totalBytes
currentBytes:(activity.currentBytes + size)];
}];
-// [[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
[queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
}
} else {
[(NSMutableDictionary *)(newObjectRequest.userInfo) setObject:[NSNumber numberWithUnsignedInteger:10] forKey:@"retries"];
[(NSMutableDictionary *)(newObjectRequest.userInfo) removeObjectForKey:@"missingBlocks"];
[(NSMutableDictionary *)(newObjectRequest.userInfo) removeObjectForKey:@"missingBlockIndex"];
-// [[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
[queue addOperation:[PithosUtilities prepareRequest:newObjectRequest priority:[[newObjectRequest.userInfo objectForKey:@"priority"] integerValue]]];
} else {
if (newSyncRequested) {
[activityFacility endActivity:activity
withMessage:[containerRequest.userInfo objectForKey:@"stoppedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (!syncOperationCount)
[self sync];
}
totalBytes:activity.totalBytes
currentBytes:(activity.currentBytes + size)];
}];
-// [[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
[queue addOperation:[PithosUtilities prepareRequest:newContainerRequest priority:[[newContainerRequest.userInfo objectForKey:@"priority"] integerValue]]];
}
}
if ([request isCancelled]) {
[activityFacility endActivity:[request.userInfo objectForKey:@"activity"]
withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
- @synchronized(self) {
- syncOperationCount--;
- }
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
return;
}
if (newSyncRequested) {
[activityFacility endActivity:[request.userInfo objectForKey:@"activity"]
withMessage:[request.userInfo objectForKey:@"stoppedActivityMessage"]];
@synchronized(self) {
- syncOperationCount--;
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
if (!syncOperationCount)
[self sync];
}
if (retries > 0) {
ASIPithosRequest *newRequest = (ASIPithosRequest *)[PithosUtilities copyRequest:request];
[(NSMutableDictionary *)(newRequest.userInfo)setObject:[NSNumber numberWithUnsignedInteger:(--retries)] forKey:@"retries"];
-// [[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]] startAsynchronous];
[queue addOperation:[PithosUtilities prepareRequest:newRequest priority:[[newRequest.userInfo objectForKey:@"priority"] integerValue]]];
} else {
[activityFacility endActivity:[request.userInfo objectForKey:@"activity"]
withMessage:[request.userInfo objectForKey:@"failedActivityMessage"]];
- @synchronized(self) {
- syncOperationCount--;
- }
+ syncIncomplete = YES;
+ [self decreaseSyncOperationCount];
}
}