diff options
author | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2015-09-02 02:57:38 -0300 |
---|---|---|
committer | Rafael Mendonça França <rafaelmfranca@gmail.com> | 2015-09-02 02:57:38 -0300 |
commit | eb8c713c987480e7a0362ae3de617ba0c0f27d7f (patch) | |
tree | 7f5b9afd7a6326161c75270701f1e880e4f20263 /lib/assets/javascripts/cable/connection_monitor.coffee | |
parent | 0cf1db6be29fb2269d722bedd690641e0f949b36 (diff) | |
download | rails-eb8c713c987480e7a0362ae3de617ba0c0f27d7f.tar.gz rails-eb8c713c987480e7a0362ae3de617ba0c0f27d7f.tar.bz2 rails-eb8c713c987480e7a0362ae3de617ba0c0f27d7f.zip |
.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.
Diffstat (limited to 'lib/assets/javascripts/cable/connection_monitor.coffee')
-rw-r--r-- | lib/assets/javascripts/cable/connection_monitor.coffee | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/lib/assets/javascripts/cable/connection_monitor.coffee b/lib/assets/javascripts/cable/connection_monitor.coffee new file mode 100644 index 0000000000..30ce11957c --- /dev/null +++ b/lib/assets/javascripts/cable/connection_monitor.coffee @@ -0,0 +1,87 @@ +# 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)) |