Close database in background thread?


#1

I’m copying the manager from the main thread so I can pass it to a background thread to create a database instance. Do I have to close the database after finished with it in the thread?

Btw do I actually have to copy the manager from the main thread, or can I just call let bgManager = CBLManager() form the background thread?

Thanks for shedding any light on this.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
  let manager = CBLManager.sharedInstance()
 ...
  let bgMgr = manager.copy()
  NSThread.detachNewThreadSelector("runBackground:", toTarget: self, withObject: bgMgr)
  return true
}

func runBackground(bgMgr: CBLManager) {
  let bgDB = bgMgr.databaseNamed("db")
  // Do stuff in datbase
  bgDB.close() ??
}

#2

You should make a copy, otherwise the two managers won’t know about each other; they need to exchange some information to work correctly.

If your background thread exits, it should close its CBLManager first.


#3

The problem that I ran into was that when closing the database in the thread, it resulted in stopping replication for all threads. However, using a 2nd manager instance instead of a copy, didn’t have that effect.


#4

If you create a Replication in both the foreground and background Database instance, they end up triggering a single replicator task (because their parameters are the same.) Then if you close the background Database it stops its Replications, which in turn stop the replicator task.

The solution is not to do that :slight_smile: Only create Replications on one thread.

(Or if you are only creating Replications on one thread, but are seeing this behavior, it sounds like a bug…)


#5

I’m not creating a second replicator. I first tried closing the database on the background thread, then did the manager like advised, but it does close the replicators used on the main thread.

In the copyWithZone function in the manager source code, it is doing this: managerCopy.replicatorClassName = _replicatorClassName;, could this have anything to do with the background close wiping all replicators on all threads, since based on your really helpful description, could cause it to create a single replicator task even though I never explicitly do this?

I’m thinking of reverting back to backgroundTellDatabaseNamed, but I like having my database tasks spread across relevant queues, instead of overloading the Couchbase maintenance thread. Do I have to close the database there?