Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A few minor connectionmanager fixes, and rate-limiting autoreconnect attempts #322

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 30 additions & 8 deletions common/lib/transport/connectionmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ var ConnectionManager = (function() {
this.proposedTransports = [];
this.pendingTransports = [];
this.host = null;
this.lastAutoReconnectAttempt = null;

Logger.logAction(Logger.LOG_MINOR, 'Realtime.ConnectionManager()', 'started');
Logger.logAction(Logger.LOG_MICRO, 'Realtime.ConnectionManager()', 'requested transports = [' + (options.transports || Defaults.transports) + ']');
Expand Down Expand Up @@ -460,8 +461,11 @@ var ConnectionManager = (function() {
* connection event, then we won't activate this transport */
var existingState = this.state;
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager.activateTransport()', 'current state = ' + existingState.state);
if(existingState.state == this.states.closing.state || existingState.state == this.states.closed.state || existingState.state == this.states.failed.state)
if(existingState.state == this.states.closing.state || existingState.state == this.states.closed.state || existingState.state == this.states.failed.state) {
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager.activateTransport()', 'Disconnecting transport and abandoning');
transport.disconnect();
return false;
}

/* remove this transport from pending transports */
Utils.arrDeleteValue(this.pendingTransports, transport);
Expand Down Expand Up @@ -575,8 +579,11 @@ var ConnectionManager = (function() {
} else if(wasActive) {
/* If we were active but there is another transport scheduled for
* activation, go into to the connecting state until that transport
* activates and sets us back to connected */
* activates and sets us back to connected. (manually starting the
* transition timers in case that never happens) */
Logger.logAction(Logger.LOG_MICRO, 'ConnectionManager.deactivateTransport()', 'wasActive but another transport is connected and scheduled for activation, so going into the connecting state until it activates');
this.startSuspendTimer();
this.startTransitionTimer(this.states.connecting);
this.notifyState({state: 'connecting', error: error});
}
};
Expand Down Expand Up @@ -709,7 +716,7 @@ var ConnectionManager = (function() {
this.transitionTimer = setTimeout(function() {
if(self.transitionTimer) {
self.transitionTimer = null;
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager connect timer expired', 'requesting new state: ' + self.states.connecting.failState);
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager ' + transitionState.state + ' timer expired', 'requesting new state: ' + transitionState.failState);
self.notifyState({state: transitionState.failState});
}
}, transitionState.retryDelay);
Expand Down Expand Up @@ -782,7 +789,7 @@ var ConnectionManager = (function() {
(this.state === this.states.connecting &&
indicated.error && Auth.isTokenErr(indicated.error))));

Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager.notifyState()', 'new state: ' + state);
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager.notifyState()', 'new state: ' + state + (retryImmediately ? '; will retry connection immediately' : ''));
/* do nothing if we're already in the indicated state */
if(state == this.state.state)
return;
Expand All @@ -802,10 +809,20 @@ var ConnectionManager = (function() {
change = new ConnectionStateChange(this.state.state, newState.state, newState.retryDelay, (indicated.error || ConnectionError[newState.state]));

if(retryImmediately) {
Utils.nextTick(function() {
self.requestState({state: 'connecting'});
});
} else if(newState.retryDelay) {
var autoReconnect = function() {
if(self.state === self.states.disconnected) {
self.lastAutoReconnectAttempt = Utils.now();
self.requestState({state: 'connecting'});
}
};
var sinceLast = this.lastAutoReconnectAttempt && (Utils.now() - this.lastAutoReconnectAttempt + 1);
if(sinceLast && (sinceLast < 1000)) {
Logger.logAction(Logger.LOG_MICRO, 'ConnectionManager.notifyState()', 'Last reconnect attempt was only ' + sinceLast + 'ms ago, waiting another ' + (1000 - sinceLast) + 'ms before trying again');
setTimeout(autoReconnect, 1000 - sinceLast);
} else {
Utils.nextTick(autoReconnect);
}
} else if(state === 'disconnected' || state === 'suspended') {
this.startRetryTimer(newState.retryDelay);
}

Expand Down Expand Up @@ -864,6 +881,11 @@ var ConnectionManager = (function() {


ConnectionManager.prototype.startConnect = function() {
if(this.state !== this.states.connecting) {
Logger.logAction(Logger.LOG_MINOR, 'ConnectionManager.startConnect()', 'Must be in connecting state to connect, but was ' + this.state.state);
return;
}

var auth = this.realtime.auth,
self = this;

Expand Down