diff options
Diffstat (limited to 'lib/assets/javascripts/cable/connection_monitor.js.coffee')
-rw-r--r-- | lib/assets/javascripts/cable/connection_monitor.js.coffee | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/lib/assets/javascripts/cable/connection_monitor.js.coffee b/lib/assets/javascripts/cable/connection_monitor.js.coffee index bb4ee8f7f6..fc5093c5eb 100644 --- a/lib/assets/javascripts/cable/connection_monitor.js.coffee +++ b/lib/assets/javascripts/cable/connection_monitor.js.coffee @@ -1,13 +1,17 @@ class Cable.ConnectionMonitor - MAX_CONNECTION_INTERVAL: 5 * 1000 - PING_STALE_INTERVAL: 8 * 1000 - identifier: Cable.PING_IDENTIFIER + pollInterval: + min: 2 + max: 30 + + staleThreshold: + startedAt: 4 + pingedAt: 8 + constructor: (@consumer) -> - @reset() @consumer.subscribers.add(this) - @pollConnection() + @start() connected: -> @reset() @@ -17,25 +21,45 @@ class Cable.ConnectionMonitor @pingedAt = now() reset: -> - @connectionAttempts = 1 + @reconnectAttempts = 0 + + start: -> + @reset() + delete @stoppedAt + @startedAt = now() + @poll() - pollConnection: -> + stop: -> + @stoppedAt = now() + + poll: -> setTimeout => - @reconnect() if @connectionIsStale() - @pollConnection() - , @getPollTimeout() + unless @stoppedAt + @reconnectIfStale() + @poll() + , @getInterval() - getPollTimeout: -> - interval = (Math.pow(2, @connectionAttempts) - 1) * 1000 - if interval > @MAX_CONNECTION_INTERVAL then @MAX_CONNECTION_INTERVAL else interval + getInterval: -> + {min, max} = @pollInterval + interval = 4 * Math.log(@reconnectAttempts + 1) + clamp(interval, min, max) * 1000 - connectionIsStale: -> - @pingedAt? and (now() - @pingedAt) > @PING_STALE_INTERVAL + reconnectIfStale: -> + if @connectionIsStale() + @reconnectAttempts += 1 + @consumer.connection.reopen() - reconnect: -> - console.log "Ping took too long to arrive. Reconnecting.." - @connectionAttempts += 1 - @consumer.connection.reopen() + connectionIsStale: -> + if @pingedAt + secondsSince(@pingedAt) > @staleThreshold.pingedAt + else + secondsSince(@startedAt) > @staleThreshold.startedAt now = -> new Date().getTime() + + secondsSince = (time) -> + (now() - time) / 1000 + + clamp = (number, min, max) -> + Math.max(min, Math.min(max, number)) |