1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/lib/assets/javascripts/cable/connection_monitor.coffee

88 lines
2.1 KiB
CoffeeScript
Raw Normal View History

2015-07-08 08:42:04 -04:00
# Responsible for ensuring the cable connection is in good health by validating the heartbeat pings sent from the server, and attempting
# revival reconnections if things go astray. Internal class, not intended for direct user manipulation.
class Cable.ConnectionMonitor
identifier: Cable.PING_IDENTIFIER
2015-06-27 16:17:00 -04:00
pollInterval:
min: 2
max: 30
staleThreshold:
startedAt: 4
pingedAt: 8
2015-06-25 16:24:58 -04:00
constructor: (@consumer) ->
@consumer.subscriptions.add(this)
2015-06-27 16:17:00 -04:00
@start()
connected: ->
@reset()
@pingedAt = now()
disconnected: ->
2015-08-31 09:14:17 -04:00
if @reconnectAttempts++ is 0
setTimeout =>
@consumer.connection.open() unless @consumer.connection.isOpen()
, 200
received: ->
@pingedAt = now()
reset: ->
2015-06-27 16:17:00 -04:00
@reconnectAttempts = 0
start: ->
@reset()
delete @stoppedAt
@startedAt = now()
@poll()
document.addEventListener("visibilitychange", @visibilityDidChange)
2015-06-27 16:17:00 -04:00
stop: ->
@stoppedAt = now()
document.removeEventListener("visibilitychange", @visibilityDidChange)
2015-06-27 16:17:00 -04:00
poll: ->
setTimeout =>
2015-06-27 16:17:00 -04:00
unless @stoppedAt
@reconnectIfStale()
@poll()
, @getInterval()
2015-06-27 16:17:00 -04:00
getInterval: ->
{min, max} = @pollInterval
interval = 4 * Math.log(@reconnectAttempts + 1)
clamp(interval, min, max) * 1000
2015-06-27 16:17:00 -04:00
reconnectIfStale: ->
if @connectionIsStale()
2015-08-31 09:14:17 -04:00
@reconnectAttempts++
2015-06-27 16:17:00 -04:00
@consumer.connection.reopen()
2015-06-27 16:17:00 -04:00
connectionIsStale: ->
if @pingedAt
secondsSince(@pingedAt) > @staleThreshold.pingedAt
else
secondsSince(@startedAt) > @staleThreshold.startedAt
visibilityDidChange: =>
if document.visibilityState is "visible"
setTimeout =>
if @connectionIsStale() or not @consumer.connection.isOpen()
@consumer.connection.reopen()
, 200
2015-07-07 09:43:22 -04:00
toJSON: ->
interval = @getInterval()
connectionIsStale = @connectionIsStale()
{@startedAt, @stoppedAt, @pingedAt, @reconnectAttempts, connectionIsStale, interval}
now = ->
new Date().getTime()
2015-06-27 16:17:00 -04:00
secondsSince = (time) ->
(now() - time) / 1000
clamp = (number, min, max) ->
Math.max(min, Math.min(max, number))