[FIX] web: fix a race condition in web client
Here is an interesting scenario, involving the reconciliation tour again (because it is our only tour that does async stuff before changing url): - web client starts normally - tour reconciliation starts, perform an rpc to find some id - web client fetches users default action, it is empty, so clicks on first menu item to load initial action, which is discuss. this will make the web client load the action with datamanager (it should be the action manager's job!). - reconciliation tour rpc completes, it changes the url, this will do a do_action - the load_action rpc from the web client completes, it will then perform a do_action, which will drop the action initiated by the tour - tour fails. The issue here is that the on_menu_action method from the web client is not really safe, from a concurrency point of view: it performs some asynchronous work, and then unilateraly decides to do a doAction. With this commit, we simply add the do_action request to the action manager, which uses internally a "dropprevious" system. This means that it will always use the last action, just as expected.
This commit is contained in:
@@ -157,27 +157,10 @@ return AbstractWebClient.extend({
|
||||
});
|
||||
},
|
||||
on_menu_action: function(options) {
|
||||
var self = this;
|
||||
return this.menu_dm.add(data_manager.load_action(options.action_id))
|
||||
.then(function (result) {
|
||||
return self.action_mutex.exec(function() {
|
||||
var completed = $.Deferred();
|
||||
self.action_manager.doAction(result, {
|
||||
clear_breadcrumbs: true,
|
||||
action_menu_id: options.id,
|
||||
}).fail(function() {
|
||||
self.menu.open_menu(options.previous_menu_id);
|
||||
}).always(function() {
|
||||
completed.resolve();
|
||||
});
|
||||
setTimeout(function() {
|
||||
completed.resolve();
|
||||
}, 2000);
|
||||
// We block the menu when clicking on an element until the action has correctly finished
|
||||
// loading. If something crash, there is a 2 seconds timeout before it's unblocked.
|
||||
return completed;
|
||||
});
|
||||
});
|
||||
this.action_manager.doAction(options.action_id, {
|
||||
clear_breadcrumbs: true,
|
||||
action_menu_id: options.id,
|
||||
});
|
||||
},
|
||||
toggle_fullscreen: function(fullscreen) {
|
||||
this._super(fullscreen);
|
||||
|
||||
Reference in New Issue
Block a user