Skip to content

Commit

Permalink
Fixing persistence concurrency issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Christoph Krey committed Apr 9, 2015
1 parent bd46f32 commit 3a91efa
Show file tree
Hide file tree
Showing 16 changed files with 143 additions and 132 deletions.
4 changes: 2 additions & 2 deletions MQTTClient.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = "MQTTClient"
s.version = "0.1.1"
s.version = "0.1.2"
s.summary = "IOS native ObjectiveC MQTT Framework"
s.homepage = "https://github.com/ckrey/MQTT-Client-Framework"
s.license = { :type => "MIT", :file => "LICENSE" }
s.author = { "Christoph Krey" => "krey.christoph@gmail.com" }
s.source = { :git => "https://github.com/ckrey/MQTT-Client-Framework.git", :tag => "0.1.1" }
s.source = { :git => "https://github.com/ckrey/MQTT-Client-Framework.git", :tag => "0.1.2" }

s.source_files = "MQTTClient/MQTTClient", "MQTTClient/MQTTClient/**/*.{h,m}"
s.requires_arc = true
Expand Down
245 changes: 128 additions & 117 deletions MQTTClient/MQTTClient/MQTTPersistence.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ @interface MQTTPersistence()
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@end

static NSRecursiveLock *lock;
static NSManagedObjectContext *parentManagedObjectContext;
static NSManagedObjectModel *managedObjectModel;
static NSPersistentStoreCoordinator *persistentStoreCoordinator;
Expand All @@ -45,6 +46,19 @@ @interface MQTTPersistence()

@implementation MQTTPersistence

- (MQTTPersistence *)init {
self = [super init];
self.persistent = PERSISTENT;
self.maxSize = MAX_SIZE;
self.maxMessages = MAX_MESSAGES;
self.maxWindowSize = MAX_WINDOW_SIZE;
if (!lock) {
lock = [[NSRecursiveLock alloc] init];
}
return self;
}


- (NSUInteger)windowSize:(NSString *)clientId {
NSUInteger windowSize = 0;
NSArray *flows = [self allFlowsforClientId:clientId
Expand Down Expand Up @@ -86,15 +100,6 @@ - (BOOL)storeMessageForClientId:(NSString *)clientId
}
}

- (MQTTPersistence *)init {
self = [super init];
self.persistent = PERSISTENT;
self.maxSize = MAX_SIZE;
self.maxMessages = MAX_MESSAGES;
self.maxWindowSize = MAX_WINDOW_SIZE;
return self;
}

- (void)deleteFlow:(MQTTFlow *)flow {
[self.managedObjectContext deleteObject:flow];
}
Expand Down Expand Up @@ -135,7 +140,7 @@ - (NSArray *)allFlowsforClientId:(NSString *)clientId
@(incomingFlag)
];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"deadline" ascending:YES]];

NSError *error = nil;
NSArray *flows = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (!flows) {
Expand Down Expand Up @@ -193,127 +198,133 @@ - (NSManagedObjectContext *)managedObjectContext
return _managedObjectContext;
}


if (parentManagedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
parentManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[parentManagedObjectContext setPersistentStoreCoordinator:coordinator];
@synchronized (lock) {
if (parentManagedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
parentManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[parentManagedObjectContext setPersistentStoreCoordinator:coordinator];
}
}

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext setParentContext:parentManagedObjectContext];

return _managedObjectContext;
}

_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_managedObjectContext setParentContext:parentManagedObjectContext];

return _managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel
{
if (managedObjectModel != nil) {
@synchronized (lock) {
if (managedObjectModel != nil) {
return managedObjectModel;
}

managedObjectModel = [[NSManagedObjectModel alloc] init];
NSMutableArray *entities = [[NSMutableArray alloc] init];
NSMutableArray *properties = [[NSMutableArray alloc] init];

NSAttributeDescription *attributeDescription;

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"clientId";
attributeDescription.attributeType = NSStringAttributeType;
attributeDescription.attributeValueClassName = @"NSString";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"incomingFlag";
attributeDescription.attributeType = NSBooleanAttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"retainedFlag";
attributeDescription.attributeType = NSBooleanAttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"commandType";
attributeDescription.attributeType = NSInteger16AttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"qosLevel";
attributeDescription.attributeType = NSInteger16AttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"messageId";
attributeDescription.attributeType = NSInteger32AttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"topic";
attributeDescription.attributeType = NSStringAttributeType;
attributeDescription.attributeValueClassName = @"NSString";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"data";
attributeDescription.attributeType = NSBinaryDataAttributeType;
attributeDescription.attributeValueClassName = @"NSData";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"deadline";
attributeDescription.attributeType = NSDateAttributeType;
attributeDescription.attributeValueClassName = @"NSDate";
[properties addObject:attributeDescription];

NSEntityDescription *entityDescription = [[NSEntityDescription alloc] init];
entityDescription.name = @"MQTTFlow";
entityDescription.managedObjectClassName = @"MQTTFlow";
entityDescription.abstract = FALSE;
entityDescription.properties = properties;

[entities addObject:entityDescription];
[managedObjectModel setEntities:entities];

return managedObjectModel;
}
managedObjectModel = [[NSManagedObjectModel alloc] init];
NSMutableArray *entities = [[NSMutableArray alloc] init];
NSMutableArray *properties = [[NSMutableArray alloc] init];

NSAttributeDescription *attributeDescription;

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"clientId";
attributeDescription.attributeType = NSStringAttributeType;
attributeDescription.attributeValueClassName = @"NSString";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"incomingFlag";
attributeDescription.attributeType = NSBooleanAttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"retainedFlag";
attributeDescription.attributeType = NSBooleanAttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"commandType";
attributeDescription.attributeType = NSInteger16AttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"qosLevel";
attributeDescription.attributeType = NSInteger16AttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"messageId";
attributeDescription.attributeType = NSInteger32AttributeType;
attributeDescription.attributeValueClassName = @"NSNumber";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"topic";
attributeDescription.attributeType = NSStringAttributeType;
attributeDescription.attributeValueClassName = @"NSString";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"data";
attributeDescription.attributeType = NSBinaryDataAttributeType;
attributeDescription.attributeValueClassName = @"NSData";
[properties addObject:attributeDescription];

attributeDescription = [[NSAttributeDescription alloc] init];
attributeDescription.name = @"deadline";
attributeDescription.attributeType = NSDateAttributeType;
attributeDescription.attributeValueClassName = @"NSDate";
[properties addObject:attributeDescription];

NSEntityDescription *entityDescription = [[NSEntityDescription alloc] init];
entityDescription.name = @"MQTTFlow";
entityDescription.managedObjectClassName = @"MQTTFlow";
entityDescription.abstract = FALSE;
entityDescription.properties = properties;

[entities addObject:entityDescription];
[managedObjectModel setEntities:entities];

return managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (persistentStoreCoordinator != nil) {
@synchronized (lock) {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}

NSURL *persistentStoreURL = [[self applicationDocumentsDirectory]
URLByAppendingPathComponent:@"MQTTClient"];
if (DEBUGPERSIST) NSLog(@"Persistent store: %@", persistentStoreURL.path);


NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES,
NSInferMappingModelAutomaticallyOption: @YES,
NSSQLiteAnalyzeOption: @YES,
NSSQLiteManualVacuumOption: @YES};

if (![persistentStoreCoordinator addPersistentStoreWithType:self.persistent ? NSSQLiteStoreType : NSInMemoryStoreType
configuration:nil
URL:self.persistent ? persistentStoreURL : nil
options:options
error:&error]) {
if (DEBUGPERSIST) NSLog(@"managedObjectContext save: %@", error);
persistentStoreCoordinator = nil;
}

return persistentStoreCoordinator;
}

NSURL *persistentStoreURL = [[self applicationDocumentsDirectory]
URLByAppendingPathComponent:@"MQTTClient"];
if (DEBUGPERSIST) NSLog(@"Persistent store: %@", persistentStoreURL.path);


NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES,
NSInferMappingModelAutomaticallyOption: @YES,
NSSQLiteAnalyzeOption: @YES,
NSSQLiteManualVacuumOption: @YES};

if (![persistentStoreCoordinator addPersistentStoreWithType:self.persistent ? NSSQLiteStoreType : NSInMemoryStoreType
configuration:nil
URL:self.persistent ? persistentStoreURL : nil
options:options
error:&error]) {
if (DEBUGPERSIST) NSLog(@"managedObjectContext save: %@", error);
persistentStoreCoordinator = nil;
}

return persistentStoreCoordinator;
}

#pragma mark - Application's Documents directory
Expand Down
Binary file modified MQTTClient/dist/MQTTClient.framework/Versions/A/MQTTClient
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@
</div><!-- fragment --></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:02 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/annotated.html
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:02 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
</table></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:02 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/classes.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:02 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/files.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:03 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/functions.html
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ <h3><a class="anchor" id="index_w"></a>- w -</h3><ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:03 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/functions_func.html
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ <h3><a class="anchor" id="index_u"></a>- u -</h3><ul>
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:03 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/functions_prop.html
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:03 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/hierarchy.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
</div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:02 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
2 changes: 1 addition & 1 deletion MQTTClient/dist/documentation/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ <h4>docs</h4>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Thu Apr 2 2015 16:42:02 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
Generated on Thu Apr 9 2015 11:09:53 for MQTTClient by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.9.1
</small></address>
Expand Down
Loading

0 comments on commit 3a91efa

Please sign in to comment.