actioncable 5.0.0.beta1.1 → 5.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -3
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +60 -44
  5. data/lib/action_cable.rb +2 -1
  6. data/lib/action_cable/channel/base.rb +2 -2
  7. data/lib/action_cable/channel/periodic_timers.rb +3 -3
  8. data/lib/action_cable/channel/streams.rb +4 -4
  9. data/lib/action_cable/connection.rb +4 -1
  10. data/lib/action_cable/connection/base.rb +22 -21
  11. data/lib/action_cable/connection/client_socket.rb +150 -0
  12. data/lib/action_cable/connection/identification.rb +1 -1
  13. data/lib/action_cable/connection/internal_channel.rb +6 -6
  14. data/lib/action_cable/connection/stream.rb +59 -0
  15. data/lib/action_cable/connection/stream_event_loop.rb +94 -0
  16. data/lib/action_cable/connection/subscriptions.rb +0 -1
  17. data/lib/action_cable/connection/web_socket.rb +14 -8
  18. data/lib/action_cable/engine.rb +3 -3
  19. data/lib/action_cable/gem_version.rb +1 -1
  20. data/lib/action_cable/remote_connections.rb +1 -1
  21. data/lib/action_cable/server.rb +0 -4
  22. data/lib/action_cable/server/base.rb +19 -22
  23. data/lib/action_cable/server/broadcasting.rb +1 -8
  24. data/lib/action_cable/server/configuration.rb +25 -5
  25. data/lib/action_cable/server/connections.rb +3 -5
  26. data/lib/action_cable/server/worker.rb +42 -13
  27. data/lib/action_cable/subscription_adapter.rb +8 -0
  28. data/lib/action_cable/subscription_adapter/async.rb +22 -0
  29. data/lib/action_cable/subscription_adapter/base.rb +28 -0
  30. data/lib/action_cable/subscription_adapter/evented_redis.rb +67 -0
  31. data/lib/action_cable/subscription_adapter/inline.rb +35 -0
  32. data/lib/action_cable/subscription_adapter/postgresql.rb +106 -0
  33. data/lib/action_cable/subscription_adapter/redis.rb +163 -0
  34. data/lib/action_cable/subscription_adapter/subscriber_map.rb +53 -0
  35. data/lib/assets/compiled/action_cable.js +473 -0
  36. data/lib/rails/generators/channel/channel_generator.rb +6 -1
  37. metadata +21 -99
  38. data/lib/action_cable/process/logging.rb +0 -10
  39. data/lib/assets/javascripts/action_cable.coffee.erb +0 -23
  40. data/lib/assets/javascripts/action_cable/connection.coffee +0 -84
  41. data/lib/assets/javascripts/action_cable/connection_monitor.coffee +0 -84
  42. data/lib/assets/javascripts/action_cable/consumer.coffee +0 -31
  43. data/lib/assets/javascripts/action_cable/subscription.coffee +0 -68
  44. data/lib/assets/javascripts/action_cable/subscriptions.coffee +0 -78
@@ -5,11 +5,16 @@ module Rails
5
5
 
6
6
  argument :actions, type: :array, default: [], banner: "method method"
7
7
 
8
+ class_option :assets, type: :boolean
9
+
8
10
  check_class_collision suffix: "Channel"
9
11
 
10
12
  def create_channel_file
11
13
  template "channel.rb", File.join('app/channels', class_path, "#{file_name}_channel.rb")
12
- template "assets/channel.coffee", File.join('app/assets/javascripts/channels', class_path, "#{file_name}.coffee")
14
+
15
+ if options[:assets]
16
+ template "assets/channel.coffee", File.join('app/assets/javascripts/channels', class_path, "#{file_name}.coffee")
17
+ end
13
18
  end
14
19
 
15
20
  protected
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actioncable
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.0.beta1.1
4
+ version: 5.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pratik Naik
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-01-25 00:00:00.000000000 Z
12
+ date: 2016-02-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -17,42 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - '='
19
19
  - !ruby/object:Gem::Version
20
- version: 5.0.0.beta1.1
20
+ version: 5.0.0.beta2
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - '='
26
26
  - !ruby/object:Gem::Version
27
- version: 5.0.0.beta1.1
27
+ version: 5.0.0.beta2
28
28
  - !ruby/object:Gem::Dependency
29
- name: coffee-rails
29
+ name: nio4r
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 4.1.0
34
+ version: '1.2'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 4.1.0
42
- - !ruby/object:Gem::Dependency
43
- name: faye-websocket
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - "~>"
47
- - !ruby/object:Gem::Version
48
- version: 0.10.0
49
- type: :runtime
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - "~>"
54
- - !ruby/object:Gem::Version
55
- version: 0.10.0
41
+ version: '1.2'
56
42
  - !ruby/object:Gem::Dependency
57
43
  name: websocket-driver
58
44
  requirement: !ruby/object:Gem::Requirement
@@ -67,76 +53,6 @@ dependencies:
67
53
  - - "~>"
68
54
  - !ruby/object:Gem::Version
69
55
  version: 0.6.1
70
- - !ruby/object:Gem::Dependency
71
- name: celluloid
72
- requirement: !ruby/object:Gem::Requirement
73
- requirements:
74
- - - "~>"
75
- - !ruby/object:Gem::Version
76
- version: 0.17.2
77
- type: :runtime
78
- prerelease: false
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - "~>"
82
- - !ruby/object:Gem::Version
83
- version: 0.17.2
84
- - !ruby/object:Gem::Dependency
85
- name: em-hiredis
86
- requirement: !ruby/object:Gem::Requirement
87
- requirements:
88
- - - "~>"
89
- - !ruby/object:Gem::Version
90
- version: 0.3.0
91
- type: :runtime
92
- prerelease: false
93
- version_requirements: !ruby/object:Gem::Requirement
94
- requirements:
95
- - - "~>"
96
- - !ruby/object:Gem::Version
97
- version: 0.3.0
98
- - !ruby/object:Gem::Dependency
99
- name: redis
100
- requirement: !ruby/object:Gem::Requirement
101
- requirements:
102
- - - "~>"
103
- - !ruby/object:Gem::Version
104
- version: '3.0'
105
- type: :runtime
106
- prerelease: false
107
- version_requirements: !ruby/object:Gem::Requirement
108
- requirements:
109
- - - "~>"
110
- - !ruby/object:Gem::Version
111
- version: '3.0'
112
- - !ruby/object:Gem::Dependency
113
- name: puma
114
- requirement: !ruby/object:Gem::Requirement
115
- requirements:
116
- - - ">="
117
- - !ruby/object:Gem::Version
118
- version: '0'
119
- type: :development
120
- prerelease: false
121
- version_requirements: !ruby/object:Gem::Requirement
122
- requirements:
123
- - - ">="
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: mocha
128
- requirement: !ruby/object:Gem::Requirement
129
- requirements:
130
- - - ">="
131
- - !ruby/object:Gem::Version
132
- version: '0'
133
- type: :development
134
- prerelease: false
135
- version_requirements: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- version: '0'
140
56
  description: Structure many real-time application concerns into channels over a single
141
57
  WebSocket connection.
142
58
  email:
@@ -160,16 +76,18 @@ files:
160
76
  - lib/action_cable/connection.rb
161
77
  - lib/action_cable/connection/authorization.rb
162
78
  - lib/action_cable/connection/base.rb
79
+ - lib/action_cable/connection/client_socket.rb
163
80
  - lib/action_cable/connection/identification.rb
164
81
  - lib/action_cable/connection/internal_channel.rb
165
82
  - lib/action_cable/connection/message_buffer.rb
83
+ - lib/action_cable/connection/stream.rb
84
+ - lib/action_cable/connection/stream_event_loop.rb
166
85
  - lib/action_cable/connection/subscriptions.rb
167
86
  - lib/action_cable/connection/tagged_logger_proxy.rb
168
87
  - lib/action_cable/connection/web_socket.rb
169
88
  - lib/action_cable/engine.rb
170
89
  - lib/action_cable/gem_version.rb
171
90
  - lib/action_cable/helpers/action_cable_helper.rb
172
- - lib/action_cable/process/logging.rb
173
91
  - lib/action_cable/remote_connections.rb
174
92
  - lib/action_cable/server.rb
175
93
  - lib/action_cable/server/base.rb
@@ -178,13 +96,16 @@ files:
178
96
  - lib/action_cable/server/connections.rb
179
97
  - lib/action_cable/server/worker.rb
180
98
  - lib/action_cable/server/worker/active_record_connection_management.rb
99
+ - lib/action_cable/subscription_adapter.rb
100
+ - lib/action_cable/subscription_adapter/async.rb
101
+ - lib/action_cable/subscription_adapter/base.rb
102
+ - lib/action_cable/subscription_adapter/evented_redis.rb
103
+ - lib/action_cable/subscription_adapter/inline.rb
104
+ - lib/action_cable/subscription_adapter/postgresql.rb
105
+ - lib/action_cable/subscription_adapter/redis.rb
106
+ - lib/action_cable/subscription_adapter/subscriber_map.rb
181
107
  - lib/action_cable/version.rb
182
- - lib/assets/javascripts/action_cable.coffee.erb
183
- - lib/assets/javascripts/action_cable/connection.coffee
184
- - lib/assets/javascripts/action_cable/connection_monitor.coffee
185
- - lib/assets/javascripts/action_cable/consumer.coffee
186
- - lib/assets/javascripts/action_cable/subscription.coffee
187
- - lib/assets/javascripts/action_cable/subscriptions.coffee
108
+ - lib/assets/compiled/action_cable.js
188
109
  - lib/rails/generators/channel/USAGE
189
110
  - lib/rails/generators/channel/channel_generator.rb
190
111
  - lib/rails/generators/channel/templates/assets/channel.coffee
@@ -209,8 +130,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
209
130
  version: 1.3.1
210
131
  requirements: []
211
132
  rubyforge_project:
212
- rubygems_version: 2.5.1
133
+ rubygems_version: 2.5.2
213
134
  signing_key:
214
135
  specification_version: 4
215
136
  summary: WebSocket framework for Rails.
216
137
  test_files: []
138
+ has_rdoc:
@@ -1,10 +0,0 @@
1
- require 'action_cable/server'
2
- require 'eventmachine'
3
- require 'celluloid'
4
-
5
- EM.error_handler do |e|
6
- puts "Error raised inside the event loop: #{e.message}"
7
- puts e.backtrace.join("\n")
8
- end
9
-
10
- Celluloid.logger = ActionCable.server.logger
@@ -1,23 +0,0 @@
1
- #= require_self
2
- #= require action_cable/consumer
3
-
4
- @ActionCable =
5
- INTERNAL: <%= ActionCable::INTERNAL.to_json %>
6
-
7
- createConsumer: (url = @getConfig("url")) ->
8
- new ActionCable.Consumer @createWebSocketURL(url)
9
-
10
- getConfig: (name) ->
11
- element = document.head.querySelector("meta[name='action-cable-#{name}']")
12
- element?.getAttribute("content")
13
-
14
- createWebSocketURL: (url) ->
15
- if url and not /^wss?:/i.test(url)
16
- a = document.createElement("a")
17
- a.href = url
18
- # Fix populating Location properties in IE. Otherwise, protocol will be blank.
19
- a.href = a.href
20
- a.protocol = a.protocol.replace("http", "ws")
21
- a.href
22
- else
23
- url
@@ -1,84 +0,0 @@
1
- # Encapsulate the cable connection held by the consumer. This is an internal class not intended for direct user manipulation.
2
-
3
- {message_types} = ActionCable.INTERNAL
4
-
5
- class ActionCable.Connection
6
- @reopenDelay: 500
7
-
8
- constructor: (@consumer) ->
9
- @open()
10
-
11
- send: (data) ->
12
- if @isOpen()
13
- @webSocket.send(JSON.stringify(data))
14
- true
15
- else
16
- false
17
-
18
- open: =>
19
- if @webSocket and not @isState("closed")
20
- throw new Error("Existing connection must be closed before opening")
21
- else
22
- @webSocket = new WebSocket(@consumer.url)
23
- @installEventHandlers()
24
- true
25
-
26
- close: ->
27
- @webSocket?.close()
28
-
29
- reopen: ->
30
- if @isState("closed")
31
- @open()
32
- else
33
- try
34
- @close()
35
- finally
36
- setTimeout(@open, @constructor.reopenDelay)
37
-
38
- isOpen: ->
39
- @isState("open")
40
-
41
- # Private
42
-
43
- isState: (states...) ->
44
- @getState() in states
45
-
46
- getState: ->
47
- return state.toLowerCase() for state, value of WebSocket when value is @webSocket?.readyState
48
- null
49
-
50
- installEventHandlers: ->
51
- for eventName of @events
52
- handler = @events[eventName].bind(this)
53
- @webSocket["on#{eventName}"] = handler
54
- return
55
-
56
- events:
57
- message: (event) ->
58
- {identifier, message, type} = JSON.parse(event.data)
59
-
60
- switch type
61
- when message_types.confirmation
62
- @consumer.subscriptions.notify(identifier, "connected")
63
- when message_types.rejection
64
- @consumer.subscriptions.reject(identifier)
65
- else
66
- @consumer.subscriptions.notify(identifier, "received", message)
67
-
68
- open: ->
69
- @disconnected = false
70
- @consumer.subscriptions.reload()
71
-
72
- close: ->
73
- @disconnect()
74
-
75
- error: ->
76
- @disconnect()
77
-
78
- disconnect: ->
79
- return if @disconnected
80
- @disconnected = true
81
- @consumer.subscriptions.notifyAll("disconnected")
82
-
83
- toJSON: ->
84
- state: @getState()
@@ -1,84 +0,0 @@
1
- # Responsible for ensuring the cable connection is in good health by validating the heartbeat pings sent from the server, and attempting
2
- # revival reconnections if things go astray. Internal class, not intended for direct user manipulation.
3
- class ActionCable.ConnectionMonitor
4
- @pollInterval:
5
- min: 3
6
- max: 30
7
-
8
- @staleThreshold: 6 # Server::Connections::BEAT_INTERVAL * 2 (missed two pings)
9
-
10
- identifier: ActionCable.INTERNAL.identifiers.ping
11
-
12
- constructor: (@consumer) ->
13
- @consumer.subscriptions.add(this)
14
- @start()
15
-
16
- connected: ->
17
- @reset()
18
- @pingedAt = now()
19
- delete @disconnectedAt
20
-
21
- disconnected: ->
22
- @disconnectedAt = now()
23
-
24
- received: ->
25
- @pingedAt = now()
26
-
27
- reset: ->
28
- @reconnectAttempts = 0
29
-
30
- start: ->
31
- @reset()
32
- delete @stoppedAt
33
- @startedAt = now()
34
- @poll()
35
- document.addEventListener("visibilitychange", @visibilityDidChange)
36
-
37
- stop: ->
38
- @stoppedAt = now()
39
- document.removeEventListener("visibilitychange", @visibilityDidChange)
40
-
41
- poll: ->
42
- setTimeout =>
43
- unless @stoppedAt
44
- @reconnectIfStale()
45
- @poll()
46
- , @getInterval()
47
-
48
- getInterval: ->
49
- {min, max} = @constructor.pollInterval
50
- interval = 5 * Math.log(@reconnectAttempts + 1)
51
- clamp(interval, min, max) * 1000
52
-
53
- reconnectIfStale: ->
54
- if @connectionIsStale()
55
- @reconnectAttempts++
56
- unless @disconnectedRecently()
57
- @consumer.connection.reopen()
58
-
59
- connectionIsStale: ->
60
- secondsSince(@pingedAt ? @startedAt) > @constructor.staleThreshold
61
-
62
- disconnectedRecently: ->
63
- @disconnectedAt and secondsSince(@disconnectedAt) < @constructor.staleThreshold
64
-
65
- visibilityDidChange: =>
66
- if document.visibilityState is "visible"
67
- setTimeout =>
68
- if @connectionIsStale() or not @consumer.connection.isOpen()
69
- @consumer.connection.reopen()
70
- , 200
71
-
72
- toJSON: ->
73
- interval = @getInterval()
74
- connectionIsStale = @connectionIsStale()
75
- {@startedAt, @stoppedAt, @pingedAt, @reconnectAttempts, connectionIsStale, interval}
76
-
77
- now = ->
78
- new Date().getTime()
79
-
80
- secondsSince = (time) ->
81
- (now() - time) / 1000
82
-
83
- clamp = (number, min, max) ->
84
- Math.max(min, Math.min(max, number))
@@ -1,31 +0,0 @@
1
- #= require action_cable/connection
2
- #= require action_cable/connection_monitor
3
- #= require action_cable/subscriptions
4
- #= require action_cable/subscription
5
-
6
- # The ActionCable.Consumer establishes the connection to a server-side Ruby Connection object. Once established,
7
- # the ActionCable.ConnectionMonitor will ensure that its properly maintained through heartbeats and checking for stale updates.
8
- # The Consumer instance is also the gateway to establishing subscriptions to desired channels through the #createSubscription
9
- # method.
10
- #
11
- # The following example shows how this can be setup:
12
- #
13
- # @App = {}
14
- # App.cable = ActionCable.createConsumer "ws://example.com/accounts/1"
15
- # App.appearance = App.cable.subscriptions.create "AppearanceChannel"
16
- #
17
- # For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.
18
- class ActionCable.Consumer
19
- constructor: (@url) ->
20
- @subscriptions = new ActionCable.Subscriptions this
21
- @connection = new ActionCable.Connection this
22
- @connectionMonitor = new ActionCable.ConnectionMonitor this
23
-
24
- send: (data) ->
25
- @connection.send(data)
26
-
27
- inspect: ->
28
- JSON.stringify(this, null, 2)
29
-
30
- toJSON: ->
31
- {@url, @subscriptions, @connection, @connectionMonitor}