1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Rework connection monitor

This commit is contained in:
Javan Makhmali 2015-06-27 16:17:00 -04:00
parent d2c613cd8f
commit 336d12f97a
4 changed files with 49 additions and 24 deletions

View file

@ -1,8 +1,5 @@
#= require cable/connection_monitor
class Cable.Connection
constructor: (@consumer) ->
new Cable.ConnectionMonitor @consumer
@open()
send: (data) ->

View file

@ -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
pollConnection: ->
start: ->
@reset()
delete @stoppedAt
@startedAt = now()
@poll()
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
reconnectIfStale: ->
if @connectionIsStale()
@reconnectAttempts += 1
@consumer.connection.reopen()
connectionIsStale: ->
@pingedAt? and (now() - @pingedAt) > @PING_STALE_INTERVAL
reconnect: ->
console.log "Ping took too long to arrive. Reconnecting.."
@connectionAttempts += 1
@consumer.connection.reopen()
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))

View file

@ -1,4 +1,5 @@
#= require cable/connection
#= require cable/connection_monitor
#= require cable/subscription
#= require cable/subscriber_manager
@ -6,6 +7,7 @@ class Cable.Consumer
constructor: (@url) ->
@subscribers = new Cable.SubscriberManager this
@connection = new Cable.Connection this
@connectionMonitor = new Cable.ConnectionMonitor this
createSubscription: (channelName, mixin) ->
channel = channelName

View file

@ -32,5 +32,7 @@ class Cable.SubscriberManager
sendCommand: (subscriber, command) ->
{identifier} = subscriber
return true if identifier is Cable.PING_IDENTIFIER
@consumer.send({command, identifier})
if identifier is Cable.PING_IDENTIFIER
@consumer.connection.isOpen()
else
@consumer.send({command, identifier})