Concurrency in couchbase-lite

54 views
Skip to first unread message

Rajeev Kumar

unread,
Oct 12, 2014, 12:43:45 PM10/12/14
to mobile-c...@googlegroups.com

I have use case where multiple threads perform CRUD operations on ios couchbase-lite database. When i refer couchbase-lite developer documentation, they suggested as below :

If your app uses Couchbase-lite on multiple threads, then on each thread (or dispatch queue) it must:

  • Create a new CBLManager instance. If you use multiple threads, do not use the sharedInstance.
  • Use only objects (Databases, Documents, ...) acquired from its Manager.
  • Not pass any Couchbase Lite objects to code running on any other thread/queue*

    I tried to create database on each thread and use it as per suggestion. But failing to create database.Getting database as nil.

Can someone suggest where things are going wrong and why database is coming as nil.

Below is my code for creating database :

+(CBLDatabase*)database {
    CBLDatabase* database = [self getThreadLocalObjectForKey:@"CBLDatabase"];
    if(!database) {
        NSError* error = nil;
        database = [[self getCBManager] databaseNamed:DATABASE_NAME error:&error];
        if(error || !database) {
            //ERROR => Database is coming as nil
            NSLog(@"serious problem occurred while opening CBL database with %@ and error => %@", DATABASE_NAME, error);
        } else {
            [self setThreadLocalObject:database forKey:@"CBLDatabase"];
        }
    }
    return database;
}

+(CBLManager*)getCBManager {
    CBLManager* manager = [self getThreadLocalObjectForKey:@"CBLManager"];
    if(!manager) {
        //        manager = [[CBLManager sharedInstance] copy];
        NSError* error;
        CBLManager *manager = [[CBLManager alloc] initWithDirectory: CBLManager.defaultDirectory options:NULL error: &error];
        if (error) {
            NSLog(@"Cannot create Manager instance with custom options");
            exit(-1);
        }else{
            [self setThreadLocalObject:manager forKey:@"CBLManager"];
        }
    }
    return manager;
}

+(id)getThreadLocalObjectForKey:(NSString*)key {
    NSMutableDictionary* threadLocalObjects = [NSThread currentThread].threadDictionary;
    return threadLocalObjects[key];
}

+(void)setThreadLocalObject:(id)object forKey:(NSString*)key {
    NSMutableDictionary* threadLocalObjects = [NSThread currentThread].threadDictionary;
    threadLocalObjects[key] = object;
}

Jens Alfke

unread,
Oct 13, 2014, 12:17:13 AM10/13/14
to mobile-c...@googlegroups.com

On Oct 12, 2014, at 9:43 AM, Rajeev Kumar <rajeevp...@gmail.com> wrote:

    CBLManager* manager = [self getThreadLocalObjectForKey:@"CBLManager"];
    if(!manager) {
        //        manager = [[CBLManager sharedInstance] copy];
        NSError* error;
        CBLManager *manager = [[CBLManager alloc] initWithDirectory: CBLManager.defaultDirectory options:NULL error: &error];


You've shadowed the variable 'manager', so after the inner block returns, the outer variable 'manager' is still nil.

It should have been pretty easy to catch this by setting a breakpoint and stepping through the code looking at the variables.

—Jens
Reply all
Reply to author
Forward
0 new messages