diff options
| author | Géry Debongnie <ged@odoo.com> | 2019-01-11 10:21:49 +0000 |
|---|---|---|
| committer | Géry Debongnie <ged@odoo.com> | 2019-01-11 10:55:19 +0000 |
| commit | 4a3f04bcc580c514c61e3bd608fa2b85065434cc (patch) | |
| tree | 8ba8d0e9c0e9c49ea6891eb8f34d9c9140312f57 /addons/web/static/src/js | |
| parent | 83f5dc8e3515a6c885b944472733ca2194d6c498 (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.
closes odoo/odoo#30136
Diffstat (limited to 'addons/web/static/src/js')
| -rw-r--r-- | addons/web/static/src/js/services/crash_manager.js | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/addons/web/static/src/js/services/crash_manager.js b/addons/web/static/src/js/services/crash_manager.js index e1da816c8e5..31aa178dc1b 100644 --- a/addons/web/static/src/js/services/crash_manager.js +++ b/addons/web/static/src/js/services/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,16 +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() { - var options = {shadow: true}; - ajax.jsonRpc('/web/webclient/version_info', 'call', {}, options).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); |
