mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Add yield to Console.nudge(), remove old exponential nudge which didn't look right
This commit is contained in:
@@ -195,10 +195,6 @@ var getCurrentProgressTracker = function () {
|
||||
return progress ? progress : rootProgress;
|
||||
};
|
||||
|
||||
var nudge = function () {
|
||||
getCurrentProgressTracker().nudge();
|
||||
};
|
||||
|
||||
var addChildTracker = function (title) {
|
||||
var options = {};
|
||||
options.title = title;
|
||||
@@ -586,6 +582,5 @@ _.extend(exports, {
|
||||
reportProgress: reportProgress,
|
||||
reportProgressDone: reportProgressDone,
|
||||
getCurrentProgressTracker: getCurrentProgressTracker,
|
||||
addChildTracker: addChildTracker,
|
||||
nudge: nudge
|
||||
addChildTracker: addChildTracker
|
||||
});
|
||||
|
||||
@@ -311,20 +311,13 @@ _.extend(LayeredCatalog.prototype, {
|
||||
var self = this;
|
||||
var uniload = require('./uniload.js');
|
||||
|
||||
var yielder = new utils.ThrottledYield();
|
||||
|
||||
var constraintSolverPackage = uniload.load({
|
||||
packages: [ 'constraint-solver']
|
||||
})['constraint-solver'];
|
||||
self.resolver =
|
||||
new constraintSolverPackage.ConstraintSolver.PackagesResolver(self, {
|
||||
nudge: function () {
|
||||
// This may be a singleton, but the resolver is in a package so it
|
||||
// doesn't have access to it.
|
||||
utils.Patience.nudge();
|
||||
buildmessage.nudge();
|
||||
|
||||
yielder.yield();
|
||||
Console.nudge(true);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -23,6 +23,7 @@ var buildmessage = require('./buildmessage.js');
|
||||
// XXX: Are we happy with chalk (and its sub-dependencies)?
|
||||
var chalk = require('chalk');
|
||||
var cleanup = require('./cleanup.js');
|
||||
var utils = require('./utils.js');
|
||||
|
||||
PROGRESS_DEBUG = !!process.env.METEOR_PROGRESS_DEBUG;
|
||||
FORCE_PRETTY=undefined;
|
||||
@@ -135,6 +136,35 @@ _.extend(ProgressDisplayStatus.prototype, {
|
||||
}
|
||||
});
|
||||
|
||||
//var spinner = ['-', '\\', '|', '/'];
|
||||
//// I looked at some Unicode indeterminate progress indicators, such as:
|
||||
////
|
||||
//// spinner = "▁▃▄▅▆▇▆▅▄▃".split('');
|
||||
//// spinner = "▉▊▋▌▍▎▏▎▍▌▋▊▉".split('');
|
||||
//// spinner = "▏▎▍▌▋▊▉▊▋▌▍▎▏▁▃▄▅▆▇▆▅▄▃".split('');
|
||||
//// spinner = "▉▊▋▌▍▎▏▎▍▌▋▊▉▇▆▅▄▃▁▃▄▅▆▇".split('');
|
||||
//// spinner = "⠉⠒⠤⣀⠤⠒".split('');
|
||||
////
|
||||
//// but none of them really seemed like an improvement. I think
|
||||
//// the case for using unicode would be stronger in a determinate
|
||||
//// progress indicator.
|
||||
////
|
||||
//// There are also some four-frame options such as ◐◓◑◒ at
|
||||
//// http://stackoverflow.com/a/2685827/157965
|
||||
//// but all of the ones I tried look terrible in the terminal.
|
||||
//if (! self.quiet) {
|
||||
// var animationFrame = 0;
|
||||
// var printUpdate = fiberHelpers.bindEnvironment(function () {
|
||||
// //runLog.logTemporary("=> Starting MongoDB... " +
|
||||
// // spinner[animationFrame]);
|
||||
// buildmessage.nudge();
|
||||
// animationFrame = (animationFrame + 1) % spinner.length;
|
||||
// });
|
||||
// printUpdate();
|
||||
// var mongoProgressTimer = setInterval(printUpdate, 200);
|
||||
//}
|
||||
|
||||
|
||||
var ProgressDisplayBar = function (console) {
|
||||
var self = this;
|
||||
|
||||
@@ -285,7 +315,6 @@ _.extend(StatusPoller.prototype, {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var Console = function (options) {
|
||||
@@ -297,7 +326,9 @@ var Console = function (options) {
|
||||
self._progressDisplay = new ProgressDisplayNone(self);
|
||||
|
||||
self._statusPoller = null;
|
||||
self._lastStatusPoll = 0;
|
||||
|
||||
self._throttledYield = new utils.ThrottledYield();
|
||||
self._throttledStatusPoll = new utils.Throttled(STATUS_INTERVAL_MS);
|
||||
|
||||
self.verbose = false;
|
||||
|
||||
@@ -382,18 +413,19 @@ _.extend(Console.prototype, {
|
||||
self.verbose = verbose;
|
||||
},
|
||||
|
||||
// XXX: Move docs from Patience.nudge()
|
||||
// Like Patience.nudge(); this can be called during long lived operations
|
||||
// where the timer may be starved off the CPU. It will execute the poll if
|
||||
// it has been 'too long'
|
||||
nudge: function () {
|
||||
nudge: function (canYield) {
|
||||
var self = this;
|
||||
var now = Date.now();
|
||||
if ((now - self._lastStatusPoll) < STATUS_INTERVAL_MS) {
|
||||
return;
|
||||
if (self._throttledStatusPoll.isAllowed()) {
|
||||
if (self._statusPoller) {
|
||||
self._statusPoller.statusPoll();
|
||||
}
|
||||
}
|
||||
// XXX: TODO: Add canYield argument and yield?
|
||||
if (self._statusPoller) {
|
||||
self._statusPoller.statusPoll();
|
||||
if (canYield === true) {
|
||||
self._throttledYield.yield();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -68,30 +68,6 @@ _.extend(Progress.prototype, {
|
||||
self.reportProgress(state);
|
||||
},
|
||||
|
||||
// For when we don't have a clear idea how long something will take,
|
||||
// (i.e. no end estimate), just call nudge occasionally. We'll build
|
||||
// an exponential progress bar for the task.
|
||||
nudge: function () {
|
||||
var self = this;
|
||||
|
||||
var halfLife = 25;
|
||||
|
||||
var state = _.clone(self._selfState);
|
||||
|
||||
if (!self._exponentialCounter) {
|
||||
self._exponentialCounter = 1;
|
||||
// Arbitrary endpoint
|
||||
state.end = 100;
|
||||
} else {
|
||||
self._exponentialCounter++;
|
||||
}
|
||||
|
||||
var fractionLeft = Math.pow(0.5, self._exponentialCounter / halfLife);
|
||||
state.current = state.end * (1 - fractionLeft);
|
||||
|
||||
self.reportProgress(state);
|
||||
},
|
||||
|
||||
// Tries to determine which is the 'current' job in the tree
|
||||
// This is very heuristical... we use some hints, like:
|
||||
// don't descend into fork-join jobs; we know these execute concurrently,
|
||||
@@ -192,7 +168,7 @@ _.extend(Progress.prototype, {
|
||||
|
||||
self._updateTotalState();
|
||||
|
||||
console.Console.nudge();
|
||||
console.Console.nudge(false);
|
||||
|
||||
self._notifyState();
|
||||
},
|
||||
|
||||
@@ -143,40 +143,11 @@ _.extend(Runner.prototype, {
|
||||
}
|
||||
|
||||
if (! self.stopped && self.mongoRunner) {
|
||||
var spinner = ['-', '\\', '|', '/'];
|
||||
// I looked at some Unicode indeterminate progress indicators, such as:
|
||||
//
|
||||
// spinner = "▁▃▄▅▆▇▆▅▄▃".split('');
|
||||
// spinner = "▉▊▋▌▍▎▏▎▍▌▋▊▉".split('');
|
||||
// spinner = "▏▎▍▌▋▊▉▊▋▌▍▎▏▁▃▄▅▆▇▆▅▄▃".split('');
|
||||
// spinner = "▉▊▋▌▍▎▏▎▍▌▋▊▉▇▆▅▄▃▁▃▄▅▆▇".split('');
|
||||
// spinner = "⠉⠒⠤⣀⠤⠒".split('');
|
||||
//
|
||||
// but none of them really seemed like an improvement. I think
|
||||
// the case for using unicode would be stronger in a determinate
|
||||
// progress indicator.
|
||||
//
|
||||
// There are also some four-frame options such as ◐◓◑◒ at
|
||||
// http://stackoverflow.com/a/2685827/157965
|
||||
// but all of the ones I tried look terrible in the terminal.
|
||||
if (! self.quiet) {
|
||||
var animationFrame = 0;
|
||||
var printUpdate = fiberHelpers.bindEnvironment(function () {
|
||||
//runLog.logTemporary("=> Starting MongoDB... " +
|
||||
// spinner[animationFrame]);
|
||||
buildmessage.nudge();
|
||||
animationFrame = (animationFrame + 1) % spinner.length;
|
||||
});
|
||||
printUpdate();
|
||||
var mongoProgressTimer = setInterval(printUpdate, 200);
|
||||
}
|
||||
|
||||
buildmessage.enterJob({ title: 'Starting MongoDB' }, function () {
|
||||
self.mongoRunner.start();
|
||||
});
|
||||
|
||||
if (! self.quiet) {
|
||||
clearInterval(mongoProgressTimer);
|
||||
if (! self.stopped)
|
||||
runLog.log("=> Started MongoDB.");
|
||||
}
|
||||
|
||||
@@ -576,6 +576,7 @@ exports.Patience = function (options) {
|
||||
}
|
||||
};
|
||||
|
||||
// XXX: Remove
|
||||
var nextYield = null;
|
||||
var YIELD_EVERY_MS = 150;
|
||||
var ACTIVE_PATIENCES = {};
|
||||
@@ -646,34 +647,48 @@ _.extend(exports.Patience.prototype, {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// This is a stripped down version of Patience, that just regulates the frequency of calling yield.
|
||||
// It should behave similarly to calling yield on every iteration of a loop,
|
||||
// except that it won't actually yield if there hasn't been a long enough time interval
|
||||
//
|
||||
// options:
|
||||
// interval: minimum interval of time between yield calls
|
||||
// (more frequent calls are simply dropped)
|
||||
//
|
||||
// XXX: Have Patience use ThrottledYield
|
||||
exports.ThrottledYield = function (options) {
|
||||
exports.Throttled = function (options) {
|
||||
var self = this;
|
||||
|
||||
options = _.extend({ interval: 150 }, options || {});
|
||||
self.interval = options.interval;
|
||||
var now = +(new Date);
|
||||
|
||||
// The next yield time is interval from now.
|
||||
self.nextYield = now + self.interval;
|
||||
self.next = now;
|
||||
};
|
||||
|
||||
_.extend(exports.Throttled.prototype, {
|
||||
isAllowed: function () {
|
||||
var self = this;
|
||||
var now = +(new Date);
|
||||
|
||||
if (now < self.next) {
|
||||
return false;
|
||||
}
|
||||
|
||||
self.next = now + self.interval;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// ThrottledYield just regulates the frequency of calling yield.
|
||||
// It should behave similarly to calling yield on every iteration of a loop,
|
||||
// except that it won't actually yield if there hasn't been a long enough time interval
|
||||
//
|
||||
// options:
|
||||
// interval: minimum interval of time between yield calls
|
||||
// (more frequent calls are simply dropped)
|
||||
exports.ThrottledYield = function (options) {
|
||||
var self = this;
|
||||
|
||||
self._throttle = new exports.Throttled(options);
|
||||
};
|
||||
|
||||
_.extend(exports.ThrottledYield.prototype, {
|
||||
yield: function () {
|
||||
var self = this;
|
||||
var now = +(new Date);
|
||||
|
||||
if (now >= self.nextYield) {
|
||||
self.nextYield = now + self.interval;
|
||||
if (self._throttle.isAllowed()) {
|
||||
utils.sleepMs(1);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user