From 741b38017c03e0877d5aa3f26fb2fe1bf6081e65 Mon Sep 17 00:00:00 2001 From: Nick Martin Date: Tue, 12 Jan 2016 16:17:35 -0800 Subject: [PATCH] Expose options `disableOplog`, `pollingInterval`, and `pollingThrottle` to `Cursor.find` These can be useful to tune performance for application specific data patterns. --- History.md | 2 ++ packages/mongo/collection.js | 3 +++ packages/mongo/oplog_observe_driver.js | 3 ++- packages/mongo/polling_observe_driver.js | 10 +++++++--- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/History.md b/History.md index 9b12d41a34..b32e7edbfe 100644 --- a/History.md +++ b/History.md @@ -15,6 +15,8 @@ * Allow `git+` URL schemes for npm dependencies #844 +* Expose options `disableOplog`, `pollingInterval`, and `pollingThrottle` to `Cursor.find` for tuning observe parameters on the server. + Patches contributed by GitHub users vereed, devgrok, ... diff --git a/packages/mongo/collection.js b/packages/mongo/collection.js index 3154c27d39..f7b5f7c2e0 100644 --- a/packages/mongo/collection.js +++ b/packages/mongo/collection.js @@ -280,6 +280,9 @@ _.extend(Mongo.Collection.prototype, { * @param {MongoFieldSpecifier} options.fields Dictionary of fields to return or exclude. * @param {Boolean} options.reactive (Client only) Default `true`; pass `false` to disable reactivity * @param {Function} options.transform Overrides `transform` on the [`Collection`](#collections) for this cursor. Pass `null` to disable transformation. + * @param {Boolean} options.disableOplog (Server only) Pass true to disable oplog-tailing on this query. This affects the way server processes calls to `observe` on this query. Disabling the oplog can be useful when working with data that updates in large batches. + * @param {Number} options.pollingInterval (Server only) How often to poll this query when observing on the server. In milliseconds. Defaults to 10 seconds. + * @param {Number} options.pollingThrottle (Server only) Minimum time to allow between re-polling. Increasing this will save CPU and mongo load at the expense of slower updates to users. Decreasing this is not recommended. In milliseconds. Defaults to 50 milliseconds. * @returns {Mongo.Cursor} */ find: function (/* selector, options */) { diff --git a/packages/mongo/oplog_observe_driver.js b/packages/mongo/oplog_observe_driver.js index e52b9960ec..024e0a817a 100644 --- a/packages/mongo/oplog_observe_driver.js +++ b/packages/mongo/oplog_observe_driver.js @@ -959,7 +959,8 @@ OplogObserveDriver.cursorSupported = function (cursorDescription, matcher) { var options = cursorDescription.options; // Did the user say no explicitly? - if (options._disableOplog) + // underscored version of the option is COMPAT with 1.2 + if (options.disableOplog || options._disableOplog) return false; // skip is not supported: to support it we would need to keep track of all diff --git a/packages/mongo/polling_observe_driver.js b/packages/mongo/polling_observe_driver.js index 5d111a1b11..feb2f85aba 100644 --- a/packages/mongo/polling_observe_driver.js +++ b/packages/mongo/polling_observe_driver.js @@ -28,7 +28,8 @@ PollingObserveDriver = function (options) { // Make sure to create a separately throttled function for each // PollingObserveDriver object. self._ensurePollIsScheduled = _.throttle( - self._unthrottledEnsurePollIsScheduled, 50 /* ms */); + self._unthrottledEnsurePollIsScheduled, + self._cursorDescription.options.pollingThrottle || 50 /* ms */); // XXX figure out if we still need a queue self._taskQueue = new Meteor._SynchronousQueue(); @@ -43,7 +44,7 @@ PollingObserveDriver = function (options) { self._pendingWrites.push(fence.beginWrite()); // Ensure a poll is scheduled... but if we already know that one is, // don't hit the throttled _ensurePollIsScheduled function (which might - // lead to us calling it unnecessarily in 50ms). + // lead to us calling it unnecessarily in ms). if (self._pollsScheduledButNotStarted === 0) self._ensurePollIsScheduled(); } @@ -60,7 +61,10 @@ PollingObserveDriver = function (options) { if (options._testOnlyPollCallback) { self._testOnlyPollCallback = options._testOnlyPollCallback; } else { - var pollingInterval = self._cursorDescription.options._pollingInterval || 10 * 1000; + var pollingInterval = + self._cursorDescription.options.pollingInterval || + self._cursorDescription.options._pollingInterval || // COMPAT with 1.2 + 10 * 1000; var intervalHandle = Meteor.setInterval( _.bind(self._ensurePollIsScheduled, self), pollingInterval); self._stopCallbacks.push(function () {