diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-11-29 20:06:16 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-11-29 20:06:16 +0100 |
| commit | ce4cc24621bf6430d7d3a2d469b375b59120c200 (patch) | |
| tree | 3837b5fe41ff88b24136ab53c871bc01f965cab1 /addons/bus/static | |
| parent | 4d7aa97da38e497fef31a06543bfa5d2c8785708 (diff) | |
| parent | 82a1e1dcc33d7c123e50d3e1aacb5e127f57c521 (diff) | |
[MERGE] forward port branch 12.0 up to 82a1e1dcc33
Diffstat (limited to 'addons/bus/static')
| -rw-r--r-- | addons/bus/static/src/js/crosstab_bus.js | 7 | ||||
| -rw-r--r-- | addons/bus/static/tests/bus_tests.js | 102 |
2 files changed, 106 insertions, 3 deletions
diff --git a/addons/bus/static/src/js/crosstab_bus.js b/addons/bus/static/src/js/crosstab_bus.js index df050b91e4c..46643cad0de 100644 --- a/addons/bus/static/src/js/crosstab_bus.js +++ b/addons/bus/static/src/js/crosstab_bus.js @@ -105,7 +105,7 @@ var CrossTabBus = Longpolling.extend({ $(window).on('unload.' + this._id, this._onUnload.bind(this)); - if (!this._callLocalStorage('getItem', 'peers')) { + if (!this._callLocalStorage('getItem', 'master')) { this._startElection(); } @@ -252,6 +252,7 @@ var CrossTabBus = Longpolling.extend({ //we're next in queue. Electing as master this.lastHeartbeat = now; this._callLocalStorage('setItem', 'heartbeat', this.lastHeartbeat); + this._callLocalStorage('setItem', 'master', true); this._isMasterTab = true; this.startPolling(); this.trigger('become_master'); @@ -297,7 +298,7 @@ var CrossTabBus = Longpolling.extend({ var value = JSON.parse(e.newValue); var key = e.key; - if (this._isRegistered && key === this._generateKey('peers') && !value) { + if (this._isRegistered && key === this._generateKey('master') && !value) { //master was unloaded this._startElection(); } @@ -341,7 +342,7 @@ var CrossTabBus = Longpolling.extend({ // unload master if (this._isMasterTab) { - this._callLocalStorage('removeItem', 'peers'); + this._callLocalStorage('removeItem', 'master'); } }, }); diff --git a/addons/bus/static/tests/bus_tests.js b/addons/bus/static/tests/bus_tests.js index 3c81398c09a..c8c7eab2bd9 100644 --- a/addons/bus/static/tests/bus_tests.js +++ b/addons/bus/static/tests/bus_tests.js @@ -214,4 +214,106 @@ QUnit.module('Bus', { }, 3); }); + + QUnit.test('cross tab bus elect new master on master unload', function (assert) { + var done = assert.async(); + assert.expect(8); + + // master + var pollDeferredMaster = $.Deferred(); + + var parentMaster = new Widget(); + testUtils.addMockEnvironment(parentMaster, { + data: {}, + services: { + bus_service: BusService, + local_storage: LocalStorageServiceMock, + }, + mockRPC: function (route, args) { + if (route === '/longpolling/poll') { + assert.step(['master', route, args.channels.join(',')]); + + pollDeferredMaster = $.Deferred(); + pollDeferredMaster.abort = (function () { + this.reject({message: "XmlHttpRequestError abort"}, $.Event()); + }).bind(pollDeferredMaster); + return pollDeferredMaster; + } + return this._super.apply(this, arguments); + } + }); + + var master = new Widget(parentMaster); + master.appendTo($('#qunit-fixture')); + + master.call('bus_service', 'onNotification', master, function (notifications) { + assert.step(['master', 'notification', notifications]); + }); + master.call('bus_service', 'addChannel', 'lambda'); + + // slave + setTimeout(function () { + var parentSlave = new Widget(); + var pollDeferredSlave = $.Deferred(); + testUtils.addMockEnvironment(parentSlave, { + data: {}, + services: { + bus_service: BusService, + local_storage: LocalStorageServiceMock, + }, + mockRPC: function (route, args) { + if (route === '/longpolling/poll') { + assert.step(['slave', route, args.channels.join(',')]); + + pollDeferredSlave = $.Deferred(); + pollDeferredSlave.abort = (function () { + this.reject({message: "XmlHttpRequestError abort"}, $.Event()); + }).bind(pollDeferredSlave); + return pollDeferredSlave; + } + return this._super.apply(this, arguments); + } + }); + + var slave = new Widget(parentSlave); + slave.appendTo($('#qunit-fixture')); + + slave.call('bus_service', 'onNotification', slave, function (notifications) { + assert.step(['slave', 'notification', notifications]); + }); + slave.call('bus_service', 'addChannel', 'lambda'); + + pollDeferredMaster.resolve([{ + id: 1, + channel: 'lambda', + message: 'beta', + }]); + + // simulate unloading master + master.call('bus_service', '_onUnload'); + + pollDeferredSlave.resolve([{ + id: 2, + channel: 'lambda', + message: 'gamma', + }]); + + assert.verifySteps([ + ["master", "/longpolling/poll", "lambda"], + ["master", "notification", [["lambda", "beta"]]], + ["slave", "notification", [["lambda", "beta"]]], + ["master", "/longpolling/poll", "lambda"], + ["slave", "/longpolling/poll", "lambda"], + ["slave", "notification", [["lambda", "gamma"]]], + ["slave", "/longpolling/poll", "lambda"], + ]); + + parentMaster.destroy(); + parentSlave.destroy(); + + done(); + + }, 3); + }); + });}); |
