mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Merge branch 'release-3.0' into release-3.0-tools
This commit is contained in:
@@ -33,22 +33,25 @@ class AsynchronousQueue {
|
||||
this._draining = false;
|
||||
}
|
||||
|
||||
async queueTask(task) {
|
||||
this._taskHandles.push({
|
||||
queueTask(task) {
|
||||
const self = this;
|
||||
self._taskHandles.push({
|
||||
task: task,
|
||||
name: task.name
|
||||
});
|
||||
await this._scheduleRun();
|
||||
self._scheduleRun();
|
||||
}
|
||||
|
||||
async _scheduleRun() {
|
||||
_scheduleRun() {
|
||||
// Already running or scheduled? Do nothing.
|
||||
if (this._runningOrRunScheduled)
|
||||
return;
|
||||
|
||||
this._runningOrRunScheduled = true;
|
||||
|
||||
await this._run();
|
||||
setImmediate(() => {
|
||||
this._run();
|
||||
});
|
||||
}
|
||||
|
||||
async _run() {
|
||||
@@ -62,29 +65,56 @@ class AsynchronousQueue {
|
||||
return;
|
||||
}
|
||||
const taskHandle = this._taskHandles.shift();
|
||||
|
||||
let exception;
|
||||
// Run the task.
|
||||
try {
|
||||
await taskHandle.task();
|
||||
} catch (err) {
|
||||
if (taskHandle.resolver) {
|
||||
// We'll throw this exception through runTask.
|
||||
exception = err;
|
||||
} else {
|
||||
Meteor._debug("Exception in queued task", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Soon, run the next task, if there is any.
|
||||
this._runningOrRunScheduled = false;
|
||||
await this._scheduleRun();
|
||||
this._scheduleRun();
|
||||
|
||||
if (taskHandle.resolver) {
|
||||
if (exception) {
|
||||
taskHandle.resolver(null, exception);
|
||||
} else {
|
||||
taskHandle.resolver();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async runTask(task) {
|
||||
let resolver;
|
||||
const promise = new Promise(
|
||||
(resolve, reject) =>
|
||||
(resolver = (res, rej) => {
|
||||
if (rej) {
|
||||
reject(rej);
|
||||
return;
|
||||
}
|
||||
resolve(res);
|
||||
})
|
||||
);
|
||||
|
||||
const handle = {
|
||||
task: Meteor.bindEnvironment(task, function(e) {
|
||||
Meteor._debug('Exception from task', e);
|
||||
throw e;
|
||||
}),
|
||||
name: task.name
|
||||
name: task.name,
|
||||
resolver,
|
||||
};
|
||||
this._taskHandles.push(handle);
|
||||
await this._scheduleRun();
|
||||
return promise;
|
||||
}
|
||||
|
||||
flush() {
|
||||
|
||||
@@ -16,10 +16,10 @@ Tinytest.add("environment - dynamic variables", function (test) {
|
||||
test.equal(CurrentFoo.get(), undefined);
|
||||
});
|
||||
|
||||
Tinytest.add("environment - bindEnvironment", function (test) {
|
||||
Tinytest.addAsync("environment - bindEnvironment", async function (test) {
|
||||
var raised_f;
|
||||
|
||||
var f = CurrentFoo.withValue(17, function () {
|
||||
var f = await CurrentFoo.withValue(17, function () {
|
||||
return Meteor.bindEnvironment(function (flag) {
|
||||
test.equal(CurrentFoo.get(), 17);
|
||||
if (flag)
|
||||
@@ -31,24 +31,24 @@ Tinytest.add("environment - bindEnvironment", function (test) {
|
||||
});
|
||||
});
|
||||
|
||||
var test_f = function () {
|
||||
var test_f = async function () {
|
||||
raised_f = null;
|
||||
|
||||
test.equal(f(false), 12);
|
||||
test.equal(await f(false), 12);
|
||||
test.equal(raised_f, null);
|
||||
|
||||
test.equal(f(true), undefined);
|
||||
test.equal(await f(true), undefined);
|
||||
test.equal(raised_f, "test");
|
||||
};
|
||||
|
||||
// At top level
|
||||
|
||||
test.equal(CurrentFoo.get(), undefined);
|
||||
test_f();
|
||||
await test_f();
|
||||
|
||||
// Inside a withValue
|
||||
|
||||
CurrentFoo.withValue(22, function () {
|
||||
await CurrentFoo.withValue(22, function () {
|
||||
test.equal(CurrentFoo.get(), 22);
|
||||
test_f();
|
||||
test.equal(CurrentFoo.get(), 22);
|
||||
@@ -61,7 +61,7 @@ Tinytest.add("environment - bindEnvironment", function (test) {
|
||||
|
||||
var raised_g;
|
||||
|
||||
var g = CurrentFoo.withValue(99, function () {
|
||||
var g = await CurrentFoo.withValue(99, function () {
|
||||
return Meteor.bindEnvironment(function (flag) {
|
||||
test.equal(CurrentFoo.get(), 99);
|
||||
|
||||
@@ -76,19 +76,19 @@ Tinytest.add("environment - bindEnvironment", function (test) {
|
||||
});
|
||||
});
|
||||
|
||||
var test_g = function () {
|
||||
var test_g = async function () {
|
||||
raised_g = null;
|
||||
|
||||
test.equal(g(false), 88);
|
||||
test.equal(await g(false), 88);
|
||||
test.equal(raised_g, null);
|
||||
|
||||
test.equal(g(true), undefined);
|
||||
test.equal(await g(true), undefined);
|
||||
test.equal(raised_g, "trial");
|
||||
};
|
||||
|
||||
test_g();
|
||||
await test_g();
|
||||
|
||||
CurrentFoo.withValue(77, function () {
|
||||
await CurrentFoo.withValue(77, function () {
|
||||
test.equal(CurrentFoo.get(), 77);
|
||||
test_g();
|
||||
test.equal(CurrentFoo.get(), 77);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
var Fiber = Npm.require('fibers');
|
||||
|
||||
Tinytest.add("fibers - synchronous queue", function (test) {
|
||||
var q = new Meteor._SynchronousQueue;
|
||||
Tinytest.addAsync("asl-sync - synchronous queue", async function (test) {
|
||||
var q = new Meteor._SynchronousQueue();
|
||||
var output = [];
|
||||
var pusher = function (n) {
|
||||
return function () {
|
||||
@@ -20,14 +18,12 @@ Tinytest.add("fibers - synchronous queue", function (test) {
|
||||
q.queueTask(pusher(1));
|
||||
outputIsUpTo(0);
|
||||
|
||||
// Run another task. After queueing it, the fiber constructed here will yield
|
||||
// back to this outer function. No task can have run yet since the main test
|
||||
// fiber still will not have yielded.
|
||||
// Run another task async to be solved in the future.
|
||||
var runTask2Done = false;
|
||||
Fiber(function () {
|
||||
q.runTask(pusher(2));
|
||||
Meteor._runAsync(async function () {
|
||||
await q.runTask(pusher(2));
|
||||
runTask2Done = true;
|
||||
}).run();
|
||||
});
|
||||
outputIsUpTo(0);
|
||||
test.isFalse(runTask2Done);
|
||||
|
||||
@@ -43,12 +39,12 @@ Tinytest.add("fibers - synchronous queue", function (test) {
|
||||
|
||||
// Run a task and block for it to be done. All queued tasks up to this one
|
||||
// will now be run.
|
||||
q.runTask(pusher(4));
|
||||
await q.runTask(pusher(4));
|
||||
outputIsUpTo(4);
|
||||
test.isTrue(runTask2Done);
|
||||
|
||||
// Task #5 is still in the queue. Run another task synchronously.
|
||||
q.runTask(pusher(6));
|
||||
await q.runTask(pusher(6));
|
||||
outputIsUpTo(6);
|
||||
|
||||
// Queue a task that throws. It'll write some debug output, but that's it.
|
||||
@@ -57,13 +53,13 @@ Tinytest.add("fibers - synchronous queue", function (test) {
|
||||
throw new Error("bla");
|
||||
});
|
||||
// let it run.
|
||||
q.runTask(pusher(7));
|
||||
await q.runTask(pusher(7));
|
||||
outputIsUpTo(7);
|
||||
|
||||
// Run a task that throws. It should throw from runTask.
|
||||
Meteor._suppress_log(1);
|
||||
test.throws(function () {
|
||||
q.runTask(function () {
|
||||
await test.throwsAsync(async function () {
|
||||
await q.runTask(function () {
|
||||
throw new Error("this is thrown");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -74,7 +74,6 @@ Package.onTest(function (api) {
|
||||
api.addFiles('dynamics_test.js', ['client', 'server']);
|
||||
|
||||
api.addFiles('fiber_helpers_test.js', ['server']);
|
||||
api.addFiles('wrapasync_test.js', ['server']);
|
||||
|
||||
api.addFiles('url_tests.js', ['client', 'server']);
|
||||
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
var asyncFunction1 = function (x, cb) {
|
||||
setTimeout(function () { cb(null, x); }, 5);
|
||||
};
|
||||
var asyncFunction2 = function (x, opt, cb) {
|
||||
if (! cb && opt instanceof Function) {
|
||||
cb = opt;
|
||||
opt = null;
|
||||
}
|
||||
asyncFunction1(x, cb);
|
||||
};
|
||||
var asyncFunction3 = function (opt, cb) {
|
||||
if (! cb && opt instanceof Function) {
|
||||
cb = opt;
|
||||
opt = null;
|
||||
}
|
||||
asyncFunction1(3, cb);
|
||||
};
|
||||
var asyncFunction4 = function (cb) {
|
||||
asyncFunction1(3, cb);
|
||||
};
|
||||
|
||||
var asyncFunction5 = function (cb) {
|
||||
var self = this;
|
||||
setTimeout(function() {
|
||||
cb(null, self);
|
||||
}, 5);
|
||||
}
|
||||
asyncFunction5.context = {};
|
||||
|
||||
var wrapped1 = Meteor.wrapAsync(asyncFunction1);
|
||||
var wrapped2 = Meteor.wrapAsync(asyncFunction2);
|
||||
var wrapped3 = Meteor.wrapAsync(asyncFunction3);
|
||||
var wrapped4 = Meteor.wrapAsync(asyncFunction4);
|
||||
var wrapped5 = Meteor.wrapAsync(
|
||||
asyncFunction5,
|
||||
asyncFunction5.context
|
||||
);
|
||||
|
||||
Tinytest.add("environment - wrapAsync sync", function (test) {
|
||||
// one required arg and callback
|
||||
test.equal(wrapped1(3), 3);
|
||||
test.equal(wrapped1(3, undefined), 3);
|
||||
// one required arg, optional second arg, callback
|
||||
test.equal(wrapped2(3), 3);
|
||||
test.equal(wrapped2(3, {foo: "bar"}), 3);
|
||||
test.equal(wrapped2(3, undefined, undefined), 3);
|
||||
test.equal(wrapped2(3, {foo: "bar"}, undefined), 3);
|
||||
// optional first arg, callback
|
||||
test.equal(wrapped3(3), 3);
|
||||
test.equal(wrapped3(3, undefined), 3);
|
||||
test.equal(wrapped3(), 3);
|
||||
test.equal(wrapped3(undefined), 3);
|
||||
// only callback
|
||||
test.equal(wrapped4(), 3);
|
||||
test.equal(wrapped4(undefined), 3);
|
||||
test.equal(wrapped5(), asyncFunction5.context);
|
||||
});
|
||||
|
||||
testAsyncMulti("environment - wrapAsync async", [
|
||||
function (test, expect) {
|
||||
var cb = function (result) {
|
||||
return expect(null, result);
|
||||
};
|
||||
// one required arg and callback
|
||||
test.equal(wrapped1(3, cb(3)), undefined);
|
||||
// one required arg, optional second arg, callback
|
||||
test.equal(wrapped2(3, cb(3)), undefined);
|
||||
test.equal(wrapped2(3, {foo: "bar"}, cb(3)), undefined);
|
||||
test.equal(wrapped2(3, undefined, cb(3)), undefined);
|
||||
// optional first arg, callback
|
||||
test.equal(wrapped3(3, cb(3)), undefined);
|
||||
test.equal(wrapped3(cb(3)), undefined);
|
||||
test.equal(wrapped3(undefined, cb(3)), undefined);
|
||||
// only callback
|
||||
test.equal(wrapped4(cb(3)), undefined);
|
||||
}
|
||||
]);
|
||||
|
||||
Tinytest.addAsync("environment - wrapAsync callback is " +
|
||||
"in fiber", function (test, onComplete) {
|
||||
var cb = function (err, result) {
|
||||
if (Meteor.isServer) {
|
||||
var Fiber = Npm.require('fibers');
|
||||
test.isTrue(Fiber.current);
|
||||
}
|
||||
onComplete();
|
||||
};
|
||||
wrapped1(3, cb);
|
||||
});
|
||||
Reference in New Issue
Block a user