How should LiveQuery handle rapid fire change requests?

97 views
Skip to first unread message

Traun Leyden

unread,
Feb 19, 2014, 9:26:49 PM2/19/14
to mobile-c...@googlegroups.com

Jens,

I have some questions around how LiveQuery currently behaves on iOS.

Quick backstory: In the couchbase lite android, there is currently a bug where the Database is not batching changes, and it's calling LiveQuery's changelistener with rapid fire change requests.  So there is a nested bug here, with the "outer" bug being the Database lack of batching behavior, and the "inner" bug being the fact that LiveQuery cannot handle it very well.  

I want to fix the inner bug first, and am trying to figure out the delta in behavior with the iOS version.  

Currently, the bug in LiveQuery (android) is:

1) fire off an async query, and save a future in a variable called updateQueryFuture 
2) fire off _another_ async query, and overwrite updateQueryFuture (losing the handle on the future from step 1)
3) user calls LiveQuery.stop()
4) the updateQueryFuture from step 2 will get cancelled, but not the updateQueryFuture from step 1.  
5) user calls Database.close()
6) the updateQueryFuture from step 1 finally runs, and throws an exception because the database has been closed from under it.

From what I can tell, in the iOS version it doesn't have this issue.  Instead:

* Rapid fire calls to LiveQuery.databaseChanged will result in multiple queries getting queued up, and they will fire asynchronously
* Calling LiveQuery.stop() will call cancelPreviousPerformRequestsWithTarget, and cancel all of them in one fell swoop.

Does this sound right?  Any other behaviors I should be aware of?

Also from looking at the _willUpdate ivar, it seems like there is the possibility of LiveQuery.stop() not actually canceling a pending query:

1) _willUpdate is NO
2) LiveQuery.databaseChanged is called, _willUpdate is set to YES
3) LiveQuery.update is called, _willUpdate is set to NO
4) LiveQuery calls runAsync with query
5) LiveQuery.stop() is called, but since  _willUpdate is set to NO, the async query is not cancelled
6) The query kicked off in step 4 finishes and calls back any listeners.  This would be unexpected behavior since stop() was previously called.

Any thoughts?


Jens Alfke

unread,
Feb 19, 2014, 9:53:22 PM2/19/14
to mobile-c...@googlegroups.com

On Feb 19, 2014, at 6:26 PM, Traun Leyden <tle...@couchbase.com> wrote:

From what I can tell, in the iOS version it doesn't have this issue.  Instead:
* Rapid fire calls to LiveQuery.databaseChanged will result in multiple queries getting queued up, and they will fire asynchronously

Depends on how rapid-fire. If -databaseChanged is called multiple times in one runloop iteration, only one async query will be triggered. (The _willUpdate flag is a guard for that.)
However, if -databaseChanged gets called on multiple runloop iterations in succession, then each of those will start an async query.

* Calling LiveQuery.stop() will call cancelPreviousPerformRequestsWithTarget, and cancel all of them in one fell swoop.

No, it only cancels the pending call to -update, of which there'll only be one.

—Jens
Reply all
Reply to author
Forward
0 new messages