summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2019-01-11 10:21:49 +0000
committerChristophe Simonis <chs@odoo.com>2019-01-28 10:55:53 +0000
commitdc751f20a2da5017644794f68af3cb0f161f77b5 (patch)
tree37aa64cf18c73ac0892d68d4973f4492df9ce68c /addons/web/static/src
parent7ab26999bebccb302c57b5c8778682bb2b5bcc88 (diff)
[FIX] web: add exponential backoff strategy for lost connection
Before this commit, the web client had a naive strategy to handle lost connections: it tried to poll the server every 2 seconds until a rpc succeeds. This works quite well from the perspective of the user, but may be a problem from the perspective of the server. If a server is down for a longish period, then each users active tabs will then perform a request every 2 seconds. This means that the server will be progressively hammered by many requests, which will clutter the logs, and make it more difficult to gracefully recover. With this commit, we simply exponentially increase the delay each time, and add a little jitter to give a better distribution. Cherry-pick of 4a3f04bcc580c514c61e3bd608fa2b85065434cc closes odoo/odoo#30136 closes odoo/odoo#30596
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/framework/crash_manager.js34
1 files changed, 24 insertions, 10 deletions
diff --git a/addons/web/static/src/js/framework/crash_manager.js b/addons/web/static/src/js/framework/crash_manager.js
index 831f762b78c..f36a04eb103 100644
--- a/addons/web/static/src/js/framework/crash_manager.js
+++ b/addons/web/static/src/js/framework/crash_manager.js
@@ -22,6 +22,7 @@ var map_title ={
var CrashManager = core.Class.extend({
init: function() {
this.active = true;
+ this.isConnected = true;
},
enable: function () {
this.active = true;
@@ -29,8 +30,29 @@ var CrashManager = core.Class.extend({
disable: function () {
this.active = false;
},
- rpc_error: function(error) {
+ handleLostConnection: function () {
var self = this;
+ if (!this.isConnected) {
+ // already handled, nothing to do. This can happen when several
+ // rpcs are done in parallel and fail because of a lost connection.
+ return;
+ }
+ this.isConnected = false;
+ var delay = 2000;
+ core.bus.trigger('connection_lost');
+
+ setTimeout(function checkConnection() {
+ ajax.jsonRpc('/web/webclient/version_info', 'call', {}, {shadow:true}).then(function () {
+ core.bus.trigger('connection_restored');
+ self.isConnected = true;
+ }).fail(function () {
+ // exponential backoff, with some jitter
+ delay = (delay * 1.5) + 500*Math.random();
+ setTimeout(checkConnection, delay);
+ });
+ }, delay);
+ },
+ rpc_error: function(error) {
if (!this.active) {
return;
}
@@ -38,15 +60,7 @@ var CrashManager = core.Class.extend({
return;
}
if (error.code == -32098) {
- core.bus.trigger('connection_lost');
- this.connection_lost = true;
- var timeinterval = setInterval(function() {
- ajax.jsonRpc('/web/webclient/version_info').then(function() {
- clearInterval(timeinterval);
- core.bus.trigger('connection_restored');
- self.connection_lost = false;
- });
- }, 2000);
+ this.handleLostConnection();
return;
}
var handler = core.crash_registry.get(error.data.name, true);