-
Notifications
You must be signed in to change notification settings - Fork 298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
After CBLLiveQuery reports an existing docID, doc has no properties yet #104
Comments
Something's wrong here. If the document isn't loadable for two seconds after the query returns, then the query isn't actually reporting that document. In your code you're looking at the key of the query row and comparing it to the UUID you want. But is the map function actually emitting the docID of the document as the key? Could you show me what your view definition looks like? |
In case its not clear, I don't know that its not available for 2 seconds. What I know is that attempting it inline inside the observeValueForKeyPath callback fails. And delaying the execution for 0 seconds also fails. And that delaying the execution for 2 seconds succeeds. It might be the case that some shorter delay would work, but I have not experimented; in fact I intentionally chose such a long delay to be more confident that it would work. We're not making a custom view, just using the canned query returned by [aDataBase queryAllDocuments] -(void) updateQueryForMissingObjects
{
if(self.missingObjects.count == 0)
{
// No missing objects, destroy the live query if it exists
if(self.observedLiveQueryForMissingObjects)
{
[self.observedLiveQueryForMissingObjects removeObserver:self forKeyPath:@"rows"];
self.observedLiveQueryForMissingObjects = nil;
}
}
else
{
// There are missing objects, create the live query if it doesn't exist
if(!self.observedLiveQueryForMissingObjects)
{
CBLQuery* query = [_database queryAllDocuments];
self.observedLiveQueryForMissingObjects = [query asLiveQuery];
[self.observedLiveQueryForMissingObjects addObserver:self forKeyPath:@"rows" options:0 context:NULL];
}
// TODO: Verify that is is safe to modify a liveQuery's 'keys' property.
// If not, we may need to destroy the query and create another one everytime our list of missing objects changes
// Update the query with the actual objects we are looking for
// 'missingObjects' is an NSMutableSet of uuid strings
self.observedLiveQueryForMissingObjects.keys = [self.missingObjects allObjects];
}
} |
What this will will do is affect the query the next time it triggers, i.e. the next time anything changes in the database. It's not going to cause the query to run immediately. And there's a race condition where, if the database just changed and the query is in the middle of running but hasn't finished yet, your changed key won't apply to that run (and the query still won't run again until there's another change.) In other words, I don't think this is going to work entirely correctly for you. If you're waiting for a specific document to show up, you can just instantiate a CBLDocument object with its ID, then observe its kCBLDocumentChangeNotification. |
I may have several documents I'm "waiting" for, but I think it might be manageable to do what you suggest: instantiate the CBLDocument objects and observe them for changes, and un-observe a given doc after I get a change for that document. Thanks, I'll give that a try. But I still think its kind of a "hole" in the API that if I instantiate a CBLDocument inside the LiveQuery callback that tells me it exists, it may return a nil properties dictionary. |
Hi @tgogolin we have not been able to reproduce, can you see if this is still happening? |
See CouchbaseMobile thread on google groups "After CBLLiveQuery reports an existing docID, doc has no properties yet?"
https://groups.google.com/forum/?fromgroups=#!topic/mobile-couchbase/KNk7flVKCCs
Summary: When responding to a CBLLiveQuery searching for a specific UUID that has just been synced to a local device, an immediate attempt to make a CBLDocument inside the observeValueForKeyPath: @"rows" code will make a CBLDocument that has no properties dictionary. You must wait an unknown period of time before you can successfully make the CBLDocument with expected properties. Note that a delay of 0.0 (just to unwind the stack before attempting to make the CBLDocument) does NOT succeed. 2.0 seconds typically does succeed.
Expected behavior: I would expect that after CBLLiveQuery has reported the existence of a docID, that it would be safe to immediately fetch that CBLDocument and examine its properties. If that is not possible, a documented way of noting when it IS safe to fetch the document properties would be appreciated.
On Google groups thread, Jens said:
BEGIN QUOTE
Sounds like a CBL bug. Could you file an issue on Github, please? I think this is a problem with the ordering of notifications, i.e. your code is getting the live-query notification before the document gets notified that it has a new revision available. It would be helpful if you could include a stack backtrace at the point where your notification handler gets called; you can do this by setting a breakpoint there and then entering “bt” in the debug console when it’s hit.
As a temporary workaround, I think you can safely reduce the wait to 0 — this isn’t a no-op, it’ll cause the delayed block to run immediately after the runloop finishes handling the current event/notification, by which time the document should have been notified. That way at least there won’t be a user-visible lag.
END QUOTE
Note: reducing the delay to zero does NOT cause the CBLDocument to be built correctly; a more substantial delay seems to be required.
Note: DMObject is our data model class, its state is the properties dictionary from a CBLDocument.
Breakpoint ONE (main thread):
change notification from CBL causes us to look for a doc with a specified uuid,
but it isn't yet in the database, so we mark it as 'missing'.
Breakpoint TWO (main thread)
LiveQuery says object is found, via observeValueForKeyPath "rows"
The text was updated successfully, but these errors were encountered: