mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Reload the client on DDP version negotiation failure
on the default connection, on the assumption that new client code will be able to negotiate successfully. Uses an exponential backoff if after reload the DDP version negotiation fails again.
This commit is contained in:
committed by
Nick Martin
parent
a741726dfc
commit
cbc28e1c7f
@@ -11,8 +11,38 @@ if (Meteor.isClient) {
|
||||
if (__meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL)
|
||||
ddpUrl = __meteor_runtime_config__.DDP_DEFAULT_CONNECTION_URL;
|
||||
}
|
||||
|
||||
var negotiationFailuresKey = "Meteor.DDPVersionNegotiationFailures";
|
||||
|
||||
var onConnected = function () {
|
||||
Meteor._localStorage.removeItem(negotiationFailuresKey);
|
||||
};
|
||||
|
||||
var exponentialBackoff = function (failures) {
|
||||
return Math.pow(failures, 1.5) * 1000;
|
||||
};
|
||||
|
||||
var onDDPVersionNegotiationFailure = function (serverRequestedVersion) {
|
||||
if (Package.reload) {
|
||||
var failures = parseInt(Meteor._localStorage.getItem(negotiationFailuresKey) || "0") + 1;
|
||||
Meteor._localStorage.setItem(negotiationFailuresKey, "" + failures);
|
||||
Meteor.setTimeout(
|
||||
function () {
|
||||
Package.reload.Reload._reload();
|
||||
},
|
||||
exponentialBackoff(failures)
|
||||
);
|
||||
}
|
||||
else {
|
||||
Meteor._debug("DDP version negotiation failed; server requested version " + serverRequestedVersion);
|
||||
}
|
||||
};
|
||||
|
||||
Meteor.connection =
|
||||
DDP.connect(ddpUrl, true /* restart_on_update */);
|
||||
DDP.connect(ddpUrl, {
|
||||
onConnected: onConnected,
|
||||
onDDPVersionNegotiationFailure: onDDPVersionNegotiationFailure
|
||||
});
|
||||
|
||||
// Proxy the public methods of Meteor.connection so they can
|
||||
// be called directly on Meteor.
|
||||
|
||||
@@ -8,16 +8,17 @@ if (Meteor.isServer) {
|
||||
// or an object as a test hook (see code)
|
||||
// Options:
|
||||
// reloadWithOutstanding: is it OK to reload if there are outstanding methods?
|
||||
// onDDPNegotiationVersionFailure: callback with the server requested version.
|
||||
var Connection = function (url, options) {
|
||||
var self = this;
|
||||
options = _.extend({
|
||||
onConnected: function () {},
|
||||
onDDPVersionNegotiationFailure: function (serverRequestedVersion, error) {
|
||||
Meteor._debug("Failed DDP connection: " + error);
|
||||
},
|
||||
// These options are only for testing.
|
||||
reloadWithOutstanding: false,
|
||||
supportedDDPVersions: SUPPORTED_DDP_VERSIONS,
|
||||
onConnectionFailure: function (reason) {
|
||||
Meteor._debug("Failed DDP connection: " + reason);
|
||||
},
|
||||
onConnected: function () {}
|
||||
supportedDDPVersions: SUPPORTED_DDP_VERSIONS
|
||||
}, options);
|
||||
|
||||
// If set, called when we reconnect, queuing method calls _before_ the
|
||||
@@ -197,7 +198,7 @@ var Connection = function (url, options) {
|
||||
var error =
|
||||
"Version negotiation failed; server requested version " + msg.version;
|
||||
self._stream.disconnect({_permanent: true, _error: error});
|
||||
options.onConnectionFailure(error);
|
||||
options.onDDPVersionNegotiationFailure(msg.version, error);
|
||||
}
|
||||
}
|
||||
else if (_.include(['added', 'changed', 'removed', 'ready', 'updated'], msg.msg))
|
||||
@@ -1378,8 +1379,8 @@ LivedataTest.Connection = Connection;
|
||||
// "/",
|
||||
// "ddp+sockjs://ddp--****-foo.meteor.com/sockjs"
|
||||
//
|
||||
DDP.connect = function (url) {
|
||||
var ret = new Connection(url);
|
||||
DDP.connect = function (url, options) {
|
||||
var ret = new Connection(url, options);
|
||||
allConnections.push(ret); // hack. see below.
|
||||
return ret;
|
||||
};
|
||||
|
||||
@@ -25,6 +25,8 @@ Package.on_use(function (api) {
|
||||
// If the facts package is loaded, publish some statistics.
|
||||
api.use('facts', 'server', {weak: true});
|
||||
|
||||
api.use('localstorage', 'client');
|
||||
|
||||
api.export('DDP');
|
||||
api.export('DDPServer', 'server');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user