mirror of
https://git.proxmox.com/git/proxmox-widget-toolkit
synced 2025-05-29 23:03:21 +00:00
fix #4421: ui: guard setProxy against races of slow vs fast requests
Some UI components use `Ext.data.Store.setProxy` to change their associated API endpoint URL in reaction to user input. One example is `BackupView`, which calls `setProxy` when the user switches from listing backups on storage A to listing backups on storage B. However, if A is slow, the UI may receive the response for A *after* the response for B. It will then display the contents of A as if they were the contents of B, resulting in a UI inconsistency. The reason is that `Ext.data.Store` still processes the slow response for A, even though it is obsolete. This patch overrides the responsible callback of `Ext.data.Store` to only process responses belonging to the currently active proxy object. This should rule out similar race conditions in all components that use the `setProxy` API. In the above example, the patch results in the response for A being ignored. Ignored responses are logged to the browser console. Note that this patch only concerns components that use `setProxy` for changing API endpoints. Other components (e.g. those using `proxy.setURL` for the same purpose) may be open to similar race conditions. Link: https://lists.proxmox.com/pipermail/pve-devel/2023-March/056062.html Signed-off-by: Friedrich Weber <f.weber@proxmox.com>
This commit is contained in:
parent
c16785f66a
commit
51083ee54a
15
src/Utils.js
15
src/Utils.js
@ -1451,3 +1451,18 @@ Ext.define('Proxmox.Async', {
|
|||||||
return new Promise((resolve, _reject) => setTimeout(resolve, millis));
|
return new Promise((resolve, _reject) => setTimeout(resolve, millis));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Ext.override(Ext.data.Store, {
|
||||||
|
// If the store's proxy is changed while it is waiting for an AJAX
|
||||||
|
// response, `onProxyLoad` will still be called for the outdated response.
|
||||||
|
// To avoid displaying inconsistent information, only process responses
|
||||||
|
// belonging to the current proxy.
|
||||||
|
onProxyLoad: function(operation) {
|
||||||
|
let me = this;
|
||||||
|
if (operation.getProxy() === me.getProxy()) {
|
||||||
|
me.callParent(arguments);
|
||||||
|
} else {
|
||||||
|
console.log(`ignored outdated response: ${operation.getRequest().getUrl()}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user