Commit dcc1c854 authored by Romain Courteaud's avatar Romain Courteaud

Mutex: execute next promise only when ALL previous promises are finished

parent ed4a061d
...@@ -272,19 +272,32 @@ ...@@ -272,19 +272,32 @@
this._latest_promise = null; this._latest_promise = null;
}; };
function doNothing() {
return;
}
Mutex.prototype = { Mutex.prototype = {
constructor: Mutex, constructor: Mutex,
lockAndRun: function lockMutexAndRun(callback) { lockAndRun: function lockMutexAndRun(callback) {
var previous_promise = this._latest_promise; var previous_promise = this._latest_promise,
returned_promise;
if (previous_promise === null) { if (previous_promise === null) {
this._latest_promise = RSVP.resolve(callback()); this._latest_promise = RSVP.resolve(callback());
} else { return this._latest_promise;
this._latest_promise = this._latest_promise
.always(function () {
return callback();
});
} }
return this._latest_promise; returned_promise = previous_promise
.always(function () {
return callback();
});
// Do not return latest promise, to not allow external caller
// to explicitely cancel it,
// ie, ensure next promise is triggered only when ALL previous
// promised are finished (not only the single previous one)
this._latest_promise = RSVP.all([
previous_promise.always(doNothing),
returned_promise.always(doNothing)
]);
return returned_promise;
} }
}; };
......
...@@ -341,7 +341,7 @@ ...@@ -341,7 +341,7 @@
counter = 0, counter = 0,
defer = RSVP.defer(); defer = RSVP.defer();
stop(); stop();
expect(8); expect(10);
function assertCounter(value) { function assertCounter(value) {
equal(counter, value); equal(counter, value);
counter += 1; counter += 1;
...@@ -364,10 +364,16 @@ ...@@ -364,10 +364,16 @@
return 'callback1 result'; return 'callback1 result';
}); });
} }
function callback3() {
// Ensure that callback3 is executed only when callback1 is finished
assertCounter(4);
return 'callback3 result';
}
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
var promise1 = mutex.lockAndRun(callback1), var promise1 = mutex.lockAndRun(callback1),
promise2 = mutex.lockAndRun(callback2); promise2 = mutex.lockAndRun(callback2),
promise3 = mutex.lockAndRun(callback3);
return RSVP.all([ return RSVP.all([
promise1, promise1,
promise2 promise2
...@@ -378,6 +384,7 @@ ...@@ -378,6 +384,7 @@
equal(error.message, 'cancel callback2'); equal(error.message, 'cancel callback2');
return 'handler2 result'; return 'handler2 result';
}), }),
promise3,
defer.promise defer.promise
.then(function () { .then(function () {
assertCounter(1); assertCounter(1);
...@@ -388,7 +395,8 @@ ...@@ -388,7 +395,8 @@
.push(function (result_list) { .push(function (result_list) {
equal(result_list[0], 'callback1 result'); equal(result_list[0], 'callback1 result');
equal(result_list[1], 'handler2 result'); equal(result_list[1], 'handler2 result');
assertCounter(4); equal(result_list[2], 'callback3 result');
assertCounter(5);
}) })
.always(function () { .always(function () {
start(); start();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment