aboutsummaryrefslogblamecommitdiffstats
path: root/lib/assets/javascripts/cable/connection_monitor.js.coffee
blob: 1f8ce4eb20e8c0a9ebf1532b0374c148177ddd05 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                             

                                   







                 
                             
                                     
            








                     






                          
 



                      
                 



                           
 



                                                   
 



                                   
 




                                                          
 




                                                                                        

                        





                                        
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()

  received: ->
    @pingedAt = now()

  reset: ->
    @reconnectAttempts = 0

  start: ->
    @reset()
    delete @stoppedAt
    @startedAt = now()
    @poll()

  stop: ->
    @stoppedAt = now()

  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 += 1
      @consumer.connection.reopen()

  connectionIsStale: ->
    if @pingedAt
      secondsSince(@pingedAt) > @staleThreshold.pingedAt
    else
      secondsSince(@startedAt) > @staleThreshold.startedAt

  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))