[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:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user