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
Rafael Mendonça França eb8c713c98 .js.coffee -> .coffee
It was initially required, but support for the shorthand has been
 supported since sprockets 2.1. Eventually 4.x will only support the
 shorthand version. Just want to get new people using the prefer stuff
 ASAP.
2015-09-02 02:57:38 -03:00

87 lines
2.1 KiB
CoffeeScript

# 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
pollInterval:
min: 2
max: 30
staleThreshold:
startedAt: 4
pingedAt: 8
constructor: (@consumer) ->
@consumer.subscriptions.add(this)
@start()
connected: ->
@reset()
@pingedAt = now()
disconnected: ->
if @reconnectAttempts++ is 0
setTimeout =>
@consumer.connection.open() unless @consumer.connection.isOpen()
, 200
received: ->
@pingedAt = now()
reset: ->
@reconnectAttempts = 0
start: ->
@reset()
delete @stoppedAt
@startedAt = now()
@poll()
document.addEventListener("visibilitychange", @visibilityDidChange)
stop: ->
@stoppedAt = now()
document.removeEventListener("visibilitychange", @visibilityDidChange)
poll: ->
setTimeout =>
unless @stoppedAt
@reconnectIfStale()
@poll()
, @getInterval()
getInterval: ->
{min, max} = @pollInterval
interval = 4 * Math.log(@reconnectAttempts + 1)
clamp(interval, min, max) * 1000
reconnectIfStale: ->
if @connectionIsStale()
@reconnectAttempts++
@consumer.connection.reopen()
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
toJSON: ->
interval = @getInterval()
connectionIsStale = @connectionIsStale()
{@startedAt, @stoppedAt, @pingedAt, @reconnectAttempts, connectionIsStale, interval}
now = ->
new Date().getTime()
secondsSince = (time) ->
(now() - time) / 1000
clamp = (number, min, max) ->
Math.max(min, Math.min(max, number))