[IMP] web: concurrency: add getUnlockedDef to mutex

This rev. adds a new function to the mutex concurrency helper:
'getUnlockedef'. This function returns a deferred resolved as soon
as the mutex has no more task to execute (or directly if it is
currently idle).

Such a function was needed for an upcoming fix.

Related to task 1878254.
This commit is contained in:
Aaron Bohy
2018-09-05 08:47:21 +02:00
parent 71254e956d
commit f29f131f85
2 changed files with 68 additions and 2 deletions
+16 -2
View File
@@ -201,6 +201,7 @@ return {
Mutex: Class.extend({
init: function () {
this.def = $.Deferred().resolve();
this.unlockedDef = undefined;
},
/**
* Add a computation to the queue, it will be executed as soon as the
@@ -210,14 +211,27 @@ return {
* @returns {Deferred}
*/
exec: function (action) {
var self = this;
var current = this.def;
var next = this.def = $.Deferred();
this.unlockedDef = this.unlockedDef || $.Deferred();
return current.then(function() {
return $.when(action()).always(function() {
return $.when(action()).always(function () {
next.resolve();
if (self.def.state() === 'resolved' && self.unlockedDef) {
self.unlockedDef.resolve();
self.unlockedDef = undefined;
}
});
});
}
},
/**
* @returns {Promise} resolved as soon as the Mutex is unlocked
* (directly if it is currently idle)
*/
getUnlockedDef: function () {
return $.when(this.unlockedDef);
},
}),
/**
* A MutexedDropPrevious is a primitive for serializing computations while
@@ -87,6 +87,58 @@ QUnit.module('core', {}, function () {
assert.strictEqual(p3.state(), "resolved");
});
QUnit.test('mutex: getUnlockedDef checks', function (assert) {
assert.expect(5);
var m = new concurrency.Mutex();
var def1 = $.Deferred();
var def2 = $.Deferred();
assert.strictEqual(m.getUnlockedDef().state(), "resolved");
m.exec(function() { return def1; });
var unlockedDef = m.getUnlockedDef();
assert.strictEqual(unlockedDef.state(), "pending");
m.exec(function() { return def2; });
assert.strictEqual(unlockedDef.state(), "pending");
def1.resolve();
assert.strictEqual(unlockedDef.state(), "pending");
def2.resolve();
assert.strictEqual(unlockedDef.state(), "resolved");
});
QUnit.test('DropPrevious: basic usecase', function (assert) {
assert.expect(5);
var dp = new concurrency.DropPrevious();
var def1 = $.Deferred();
var def2 = $.Deferred();
var r1 = dp.add(def1);
assert.strictEqual(r1.state(), "pending");
var r2 = dp.add(def2);
assert.strictEqual(r1.state(), "rejected");
assert.strictEqual(r2.state(), "pending");
def2.resolve();
assert.strictEqual(r1.state(), "rejected");
assert.strictEqual(r2.state(), "resolved");
});
QUnit.test('DropMisordered: resolve all correctly ordered, sync', function (assert) {
assert.expect(1);