[FIX] web: action service: concurrency issue

There is a concurrency issue in the action service:
 1) be in an action with several views
 2) execute another action (e.g. by clicking on a menu)
  -> [calls the route "/web/action/load", and it takes a while]
 3) meanwhile, click on another view in the view switcher

If the call to "/web/action/load" is long enough, it may happen
that the view requested in step 3 is briefly shown before the
action associated with the menu clicked in step 2.

In this scenario, the action of step 2 should never be displayed,
because the user requested something else afterwards (in this
case a switch view).

One can produce a similar issue when restoring a previous action
of the breadcrumbs instead of switching view.

This commit fixes those two issues by registering a resolved
promise in the keepLast (concurrency utils), s.t. it "cancels"
the potential current operation (in this case, the call to
"/web/load/action").

closes odoo/odoo#87204

X-original-commit: fb9c8cd6fee476d2506b8c1338bf88c4520ea7b6
Signed-off-by: Mathieu Duckerts-Antoine <dam@odoo.com>
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
Aaron Bohy
2022-03-24 21:38:44 +01:00
parent 714948cb97
commit e5db9d8743
2 changed files with 80 additions and 0 deletions
@@ -1237,6 +1237,7 @@ function makeActionManager(env) {
* @returns {Promise<Number>}
*/
async function switchView(viewType, props = {}) {
await keepLast.add(Promise.resolve());
const controller = controllerStack[controllerStack.length - 1];
const view = _getView(viewType);
if (!view) {
@@ -1296,6 +1297,7 @@ function makeActionManager(env) {
* @param {string} jsId
*/
async function restore(jsId) {
await keepLast.add(Promise.resolve());
let index;
if (!jsId) {
index = controllerStack.length - 2;