Document not updated in time between threads

19 views
Skip to first unread message

Tristan Richard

unread,
Nov 19, 2016, 9:12:57 PM11/19/16
to Couchbase Mobile
At the time the observer is called the changes have not been committed to the main thread.
Can anyone help?
Database.sharedIntance.getManager().backgroundTellDatabaseNamed(database, to: { (db: CBLDatabase!) -> Void in let document = db.documentWithID(key) // Add Observer to document if document != nil && completionClosure != nil { let mainQueue = NSOperationQueue.mainQueue() NSNotificationCenter.defaultCenter().addObserverForName(kCBLDocumentChangeNotification, object: document, queue: mainQueue) { (notification) -> Void in debugPrint(notification.userInfo!) if let change = notification.userInfo!["change"] as? CBLDatabaseChange { debugPrint("This is a new revision, %@", change.revisionID); completionClosure?() } } } do { var properties = document?.properties if properties == nil { properties = serializedObject } else { properties?.merge(withDictionary: serializedObject) } try document?.putProperties(properties!) } catch { let nsError = error as NSError debugPrint("Failed to write object with key: \(key) to cache with error: \(nsError.localizedDescription)") ThreadController.performBlockOnMainQueue{ completionClosure?() } } })

Jens Alfke

unread,
Nov 21, 2016, 2:08:12 PM11/21/16
to mobile-c...@googlegroups.com
The code you posted got squished onto one line and isn’t readable.

Did you already ask this question on the Couchbase forums? It sounds familiar. My answer there was that changes won’t be visible to other threads (which have their own database connections) until the transaction is committed. 

Unfortunately, the transaction doesn’t commit until just after your async block returns, so a notification or other callout from your block will run too early. This looks like a limitation in our API; it totally makes sense that you’d want to schedule something to be called after the background operation completes.

As a workaround, I think issuing a delayed-perform at the end of the block will work. This will run on the background thread but after the transaction has been committed, so at that point you can notify the main thread.

// … make changes to documents…
NSRunLoop.defaultRunLoop.performBlock {
ThreadController.performBlockOnMainQueue{ completionClosure?()}
}

—Jens
Reply all
Reply to author
Forward
0 new messages