aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee
diff options
context:
space:
mode:
Diffstat (limited to 'actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee')
-rw-r--r--actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee78
1 files changed, 47 insertions, 31 deletions
diff --git a/actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee b/actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee
index 99b9a1c6d5..0cc675fa94 100644
--- a/actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee
+++ b/actioncable/app/assets/javascripts/action_cable/connection_monitor.coffee
@@ -7,54 +7,69 @@ class ActionCable.ConnectionMonitor
@staleThreshold: 6 # Server::Connections::BEAT_INTERVAL * 2 (missed two pings)
- identifier: ActionCable.INTERNAL.identifiers.ping
+ constructor: (@connection) ->
+ @reconnectAttempts = 0
- constructor: (@consumer) ->
- @consumer.subscriptions.add(this)
- @start()
+ start: ->
+ unless @isRunning()
+ @startedAt = now()
+ delete @stoppedAt
+ @startPolling()
+ document.addEventListener("visibilitychange", @visibilityDidChange)
+ ActionCable.log("ConnectionMonitor started. pollInterval = #{@getPollInterval()} ms")
- connected: ->
- @reset()
- @pingedAt = now()
- delete @disconnectedAt
+ stop: ->
+ if @isRunning()
+ @stoppedAt = now()
+ @stopPolling()
+ document.removeEventListener("visibilitychange", @visibilityDidChange)
+ ActionCable.log("ConnectionMonitor stopped")
- disconnected: ->
- @disconnectedAt = now()
+ isRunning: ->
+ @startedAt? and not @stoppedAt?
- received: ->
+ recordPing: ->
@pingedAt = now()
- reset: ->
+ recordConnect: ->
@reconnectAttempts = 0
+ @recordPing()
+ delete @disconnectedAt
+ ActionCable.log("ConnectionMonitor recorded connect")
- start: ->
- @reset()
- delete @stoppedAt
- @startedAt = now()
+ recordDisconnect: ->
+ @disconnectedAt = now()
+ ActionCable.log("ConnectionMonitor recorded disconnect")
+
+ # Private
+
+ startPolling: ->
+ @stopPolling()
@poll()
- document.addEventListener("visibilitychange", @visibilityDidChange)
- stop: ->
- @stoppedAt = now()
- document.removeEventListener("visibilitychange", @visibilityDidChange)
+ stopPolling: ->
+ clearTimeout(@pollTimeout)
poll: ->
- setTimeout =>
- unless @stoppedAt
- @reconnectIfStale()
- @poll()
- , @getInterval()
+ @pollTimeout = setTimeout =>
+ @reconnectIfStale()
+ @poll()
+ , @getPollInterval()
- getInterval: ->
+ getPollInterval: ->
{min, max} = @constructor.pollInterval
interval = 5 * Math.log(@reconnectAttempts + 1)
- clamp(interval, min, max) * 1000
+ Math.round(clamp(interval, min, max) * 1000)
reconnectIfStale: ->
if @connectionIsStale()
+ ActionCable.log("ConnectionMonitor detected stale connection. reconnectAttempts = #{@reconnectAttempts}, pollInterval = #{@getPollInterval()} ms, time disconnected = #{secondsSince(@disconnectedAt)} s, stale threshold = #{@constructor.staleThreshold} s")
@reconnectAttempts++
- unless @disconnectedRecently()
- @consumer.connection.reopen()
+ if @disconnectedRecently()
+ ActionCable.log("ConnectionMonitor skipping reopening recent disconnect")
+ else
+ ActionCable.log("ConnectionMonitor reopening")
+ @connection.reopen()
connectionIsStale: ->
secondsSince(@pingedAt ? @startedAt) > @constructor.staleThreshold
@@ -65,8 +80,9 @@ class ActionCable.ConnectionMonitor
visibilityDidChange: =>
if document.visibilityState is "visible"
setTimeout =>
- if @connectionIsStale() or not @consumer.connection.isOpen()
- @consumer.connection.reopen()
+ if @connectionIsStale() or not @connection.isOpen()
+ ActionCable.log("ConnectionMonitor reopening stale connection on visibilitychange. visbilityState = #{document.visibilityState}")
+ @connection.reopen()
, 200
now = ->