[FIX] web_kanban: fix race condition in do_search

The do_search method still had a race condition because the
read_slice method of datasets alter ids.  So, what could happen is
this: a long search is started, then a shorter search is started and
ended before the first search is completed.  The ui is rendered
properly, but then the long search ends and alter the dataset.  As
a result, the Kanban view is broken (cannot open a record anymore
because the dataset has the wrong ids).

This commit fixes the issue by doing basically what the read_slice
method did, except the ids altering part.  However, it introduced
a new problem for x2many kanban views: these kanban view don't have
the same dataset, they have a datasetstatic. The naive substitution
does not work, so I had to reintroduce the old method in X2ManyKanbanView.
This commit is contained in:
Géry Debongnie
2016-04-07 14:16:04 +02:00
parent a658b9030a
commit 6859c8dacb
2 changed files with 33 additions and 17 deletions
@@ -15,6 +15,22 @@ var X2ManyKanbanView = KanbanView.extend({
}); });
this._super($node, options); this._super($node, options);
}, },
load_records: function (offset, dataset) {
var options = {
'limit': this.limit,
'offset': offset,
};
dataset = dataset || this.dataset;
return dataset
.read_slice(this.fields_keys.concat(['__last_update']), options)
.then(function(records) {
return {
records: records,
is_empty: !records.length,
grouped: false,
};
});
},
}); });
var One2ManyKanbanView = X2ManyKanbanView.extend({ var One2ManyKanbanView = X2ManyKanbanView.extend({
@@ -86,4 +102,3 @@ core.view_registry.add('one2many_kanban', One2ManyKanbanView);
core.view_registry.add('many2many_kanban', Many2ManyKanbanView); core.view_registry.add('many2many_kanban', Many2ManyKanbanView);
}); });
+16 -15
View File
@@ -130,13 +130,16 @@ var KanbanView = View.extend({
return this.search_orderer return this.search_orderer
.add(options.grouped ? this.load_groups(options) : this.load_records()) .add(options.grouped ? this.load_groups(options) : this.load_records())
.then(function (data) { .then(function (data) {
var new_ids;
_.extend(self, options); _.extend(self, options);
if (options.grouped) { if (options.grouped) {
var new_ids = _.union.apply(null, _.map(data.groups, function (group) { new_ids = _.union.apply(null, _.map(data.groups, function (group) {
return group.dataset.ids; return group.dataset.ids;
})); }));
self.dataset.alter_ids(new_ids); } else {
new_ids = _.pluck(data.records, 'id');
} }
self.dataset.alter_ids(new_ids);
self.data = data; self.data = data;
}) })
.then(this.proxy('render')) .then(this.proxy('render'))
@@ -153,20 +156,18 @@ var KanbanView = View.extend({
}, },
load_records: function (offset, dataset) { load_records: function (offset, dataset) {
var options = {
'limit': this.limit,
'offset': offset,
};
dataset = dataset || this.dataset; dataset = dataset || this.dataset;
return dataset return dataset._model.query(this.fields_keys.concat(['__last_update']))
.read_slice(this.fields_keys.concat(['__last_update']), options) .limit(this.limit || false)
.then(function(records) { .offset(offset || 0)
return { .all()
records: records, .then(function (records) {
is_empty: !records.length, return {
grouped: false, records: records,
}; is_empty: !records.length,
}); grouped: false,
};
});
}, },
load_groups: function (options) { load_groups: function (options) {