From b4e02f345a40db826ceae9da318f5532e8d6714e Mon Sep 17 00:00:00 2001 From: David Glasser Date: Tue, 29 Jul 2014 10:18:40 -0700 Subject: [PATCH] Fix a few exceptions in the oplog observe driver First exception: _runQuery didn't check to see if it was stopped after running the query, which could lead to this harmless error: Exception in defer callback: TypeError: Cannot call method 'clear' of null at _.extend._publishNewResults (packages/mongo-livedata/oplog_observe_driver.js:749) at _.extend._runQuery (packages/mongo-livedata/oplog_observe_driver.js:657) at packages/mongo-livedata/oplog_observe_driver.js:615 at _.extend.withValue (packages/meteor/dynamics_nodejs.js:56) at packages/meteor/timers.js:6 at runWithEnvironment (packages/meteor/dynamics_nodejs.js:108) Second exception: _fetchModifiedDocuments thought that it should only be in FETCHING in a certain case, but QUERYING is also OK. This is also harmless since the correct behavior is to end the deferred routine. Exception in defer callback: Error: phase in fetchModifiedDocuments: QUERYING at packages/mongo-livedata/oplog_observe_driver.js:435 at packages/mongo-livedata/oplog_observe_driver.js:16 at _.extend.withValue (packages/meteor/dynamics_nodejs.js:56) at packages/meteor/timers.js:6 at runWithEnvironment (packages/meteor/dynamics_nodejs.js:108) --- packages/mongo-livedata/oplog_observe_driver.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/mongo-livedata/oplog_observe_driver.js b/packages/mongo-livedata/oplog_observe_driver.js index ac03d24cb0..d9348a62b1 100644 --- a/packages/mongo-livedata/oplog_observe_driver.js +++ b/packages/mongo-livedata/oplog_observe_driver.js @@ -431,6 +431,14 @@ _.extend(OplogObserveDriver.prototype, { // fetch() yields. Meteor.defer(finishIfNeedToPollQuery(function () { while (!self._stopped && !self._needToFetch.empty()) { + if (self._phase === PHASE.QUERYING) { + // While fetching, we decided to go into QUERYING mode, and then we + // saw another oplog entry, so _needToFetch is not empty. But we + // shouldn't fetch these documents until AFTER the query is done. + break; + } + + // Being in steady phase here would be surprising. if (self._phase !== PHASE.FETCHING) throw new Error("phase in fetchModifiedDocuments: " + self._phase); @@ -654,6 +662,9 @@ _.extend(OplogObserveDriver.prototype, { } } + if (self._stopped) + return; + self._publishNewResults(newResults, newBuffer); }, @@ -789,6 +800,9 @@ _.extend(OplogObserveDriver.prototype, { // This stop function is invoked from the onStop of the ObserveMultiplexer, so // it shouldn't actually be possible to call it until the multiplexer is // ready. + // + // It's important to check self._stopped after every call in this file that + // can yield! stop: function () { var self = this; if (self._stopped)