Merge pull request #357 from sharelatex/bg-rate-limit-on-reconnects

rate limit on reconnects
This commit is contained in:
Brian Gough 2016-11-01 15:09:50 +00:00 committed by GitHub
commit 4623f3cbe7

View file

@ -36,16 +36,19 @@ define [], () ->
inactive_disconnect: false
@$scope.tryReconnectNow = () =>
@tryReconnect()
# user manually requested reconnection via "Try now" button
@tryReconnectWithRateLimit({force:true})
@$scope.$on 'cursor:editor:update', () =>
@lastUserAction = new Date()
@lastUserAction = new Date() # time of last edit
if !@connected
@tryReconnect()
# user is editing, try to reconnect
@tryReconnectWithRateLimit()
document.querySelector('body').addEventListener 'click', (e) =>
if !@connected and e.target.id != 'try-reconnect-now-button'
@tryReconnect()
# user is editing, try to reconnect
@tryReconnectWithRateLimit()
@ide.socket = io.connect null,
reconnect: false
@ -166,11 +169,13 @@ define [], () ->
@tryReconnect()
disconnect: () ->
sl_console.log "[socket.io] disconnecting client"
@ide.socket.disconnect()
startAutoReconnectCountdown: () ->
sl_console.log "[ConnectionManager] starting autoreconnect countdown"
twoMinutes = 2 * 60 * 1000
if @lastUpdated? and new Date() - @lastUpdated > twoMinutes
if @lastUserAction? and new Date() - @lastUserAction > twoMinutes
# between 1 minute and 3 minutes
countdown = 60 + Math.floor(Math.random() * 120)
else
@ -189,10 +194,16 @@ define [], () ->
, 200)
cancelReconnect: () ->
clearTimeout @timeoutId if @timeoutId?
# clear timeout and set to null so we know there is no countdown running
if @timeoutId?
sl_console.log "[ConnectionManager] cancelling existing reconnect timer"
clearTimeout @timeoutId
@timeoutId = null
decreaseCountdown: () ->
@timeoutId = null
return if !@$scope.connection.reconnection_countdown?
sl_console.log "[ConnectionManager] decreasing countdown", @$scope.connection.reconnection_countdown
@$scope.$apply () =>
@$scope.connection.reconnection_countdown--
@ -203,13 +214,33 @@ define [], () ->
@timeoutId = setTimeout (=> @decreaseCountdown()), 1000
tryReconnect: () ->
sl_console.log "[ConnectionManager] tryReconnect"
@cancelReconnect()
delete @$scope.connection.reconnection_countdown
return if @connected
@$scope.connection.reconnecting = true
@ide.socket.socket.reconnect()
# use socket.io connect() here to make a single attempt, the
# reconnect() method makes multiple attempts
@ide.socket.socket.connect()
# record the time of the last attempt to connect
@lastConnectionAttempt = new Date()
setTimeout (=> @startAutoReconnectCountdown() if !@connected), 2000
MIN_RETRY_INTERVAL: 1000 # ms
BACKGROUND_RETRY_INTERVAL : 30 * 1000 # ms
tryReconnectWithRateLimit: (options) ->
# bail out if the reconnect is already in progress
return if @$scope.connection?.reconnecting
# bail out if we are going to reconnect soon anyway
reconnectingSoon = @$scope.connection?.reconnection_countdown? and @$scope.connection.reconnection_countdown <= 5
clickedTryNow = options?.force # user requested reconnection
return if reconnectingSoon and not clickedTryNow
# bail out if we tried reconnecting recently
allowedInterval = if clickedTryNow then @MIN_RETRY_INTERVAL else @BACKGROUND_RETRY_INTERVAL
return if @lastConnectionAttempt? and new Date() - @lastConnectionAttempt < allowedInterval
@tryReconnect()
disconnectIfInactive: ()->
@userIsInactive = (new Date() - @lastUserAction) > @disconnectAfterMs
if @userIsInactive and @connected