[FIX] web: use mutex to wait for onchanges

This fix is related to c12a2e1d16

Mutex allow to wait sequentially for mutex
Besides, if one of the onchanges deferreds fails, it does not resolve the mutex until all deferreds of the mutex are resolved.

Besides, we now wait for the onchanges mutex between each field commited value (line 596) in case the commited value leaded to a new onchanges, that we should wait for before commiting the rest of the values.
This commit is contained in:
Denis Ledoux 2014-11-28 13:36:42 +01:00
parent 479d94ea14
commit 45551cf78c
1 changed files with 46 additions and 48 deletions

View File

@ -103,7 +103,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
this.fields_order = [];
this.datarecord = {};
this._onchange_specs = {};
this.onchanges_defs = [];
this.onchanges_mutex = new $.Mutex();
this.default_focus_field = null;
this.default_focus_button = null;
this.fields_registry = instance.web.form.widgets;
@ -509,44 +509,45 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
def = self.alive(new instance.web.Model(self.dataset.model).call(
"onchange", [ids, values, trigger_field_name, onchange_specs, context]));
}
var onchange_def = def.then(function(response) {
if (widget && widget.field['change_default']) {
var fieldname = widget.name;
var value_;
if (response.value && (fieldname in response.value)) {
// Use value from onchange if onchange executed
value_ = response.value[fieldname];
} else {
// otherwise get form value for field
value_ = self.fields[fieldname].get_value();
}
var condition = fieldname + '=' + value_;
this.onchanges_mutex.exec(function(){
return def.then(function(response) {
if (widget && widget.field['change_default']) {
var fieldname = widget.name;
var value_;
if (response.value && (fieldname in response.value)) {
// Use value from onchange if onchange executed
value_ = response.value[fieldname];
} else {
// otherwise get form value for field
value_ = self.fields[fieldname].get_value();
}
var condition = fieldname + '=' + value_;
if (value_) {
return self.alive(new instance.web.Model('ir.values').call(
'get_defaults', [self.model, condition]
)).then(function (results) {
if (!results.length) {
if (value_) {
return self.alive(new instance.web.Model('ir.values').call(
'get_defaults', [self.model, condition]
)).then(function (results) {
if (!results.length) {
return response;
}
if (!response.value) {
response.value = {};
}
for(var i=0; i<results.length; ++i) {
// [whatever, key, value]
var triplet = results[i];
response.value[triplet[1]] = triplet[2];
}
return response;
}
if (!response.value) {
response.value = {};
}
for(var i=0; i<results.length; ++i) {
// [whatever, key, value]
var triplet = results[i];
response.value[triplet[1]] = triplet[2];
}
return response;
});
});
}
}
}
return response;
}).then(function(response) {
return self.on_processed_onchange(response);
return response;
}).then(function(response) {
return self.on_processed_onchange(response);
});
});
this.onchanges_defs.push(onchange_def);
return onchange_def;
return this.onchanges_mutex.def;
} catch(e) {
console.error(e);
instance.webclient.crashmanager.show_message(e);
@ -587,21 +588,18 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
var self = this;
return this.mutating_mutex.exec(function() {
function iterate() {
var start = $.Deferred();
start.resolve();
start = _.reduce(self.onchanges_defs, function(memo, d){
return memo.then(function(){
return d;
}, function(){
return d;
});
}, start);
var defs = [start];
var mutex = new $.Mutex();
_.each(self.fields, function(field) {
defs.push(field.commit_value());
self.onchanges_mutex.def.then(function(){
mutex.exec(function(){
return field.commit_value();
});
});
});
var args = _.toArray(arguments);
return $.when.apply($, defs).then(function() {
return $.when.apply(null, [mutex.def, self.onchanges_mutex.def]).then(function() {
var save_obj = self.save_list.pop();
if (save_obj) {
return self._process_save(save_obj).then(function() {
@ -655,7 +653,7 @@ instance.web.FormView = instance.web.View.extend(instance.web.form.FieldManagerM
* if the current record is not yet saved. It will then stay in create mode.
*/
to_edit_mode: function() {
this.onchanges_defs = [];
this.onchanges_mutex = new $.Mutex();
this._actualize_mode("edit");
},
/**