actioncable 5.1.7 → 5.2.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.md +14 -103
- data/README.md +6 -6
- data/lib/action_cable.rb +2 -0
- data/lib/action_cable/channel.rb +2 -0
- data/lib/action_cable/channel/base.rb +6 -2
- data/lib/action_cable/channel/broadcasting.rb +2 -0
- data/lib/action_cable/channel/callbacks.rb +2 -0
- data/lib/action_cable/channel/naming.rb +2 -0
- data/lib/action_cable/channel/periodic_timers.rb +3 -2
- data/lib/action_cable/channel/streams.rb +2 -0
- data/lib/action_cable/connection.rb +2 -0
- data/lib/action_cable/connection/authorization.rb +2 -0
- data/lib/action_cable/connection/base.rb +3 -1
- data/lib/action_cable/connection/client_socket.rb +3 -1
- data/lib/action_cable/connection/identification.rb +3 -2
- data/lib/action_cable/connection/internal_channel.rb +2 -0
- data/lib/action_cable/connection/message_buffer.rb +2 -0
- data/lib/action_cable/connection/stream.rb +2 -0
- data/lib/action_cable/connection/stream_event_loop.rb +2 -0
- data/lib/action_cable/connection/subscriptions.rb +3 -1
- data/lib/action_cable/connection/tagged_logger_proxy.rb +2 -0
- data/lib/action_cable/connection/web_socket.rb +3 -1
- data/lib/action_cable/engine.rb +2 -0
- data/lib/action_cable/gem_version.rb +5 -3
- data/lib/action_cable/helpers/action_cable_helper.rb +2 -0
- data/lib/action_cable/remote_connections.rb +7 -2
- data/lib/action_cable/server.rb +2 -0
- data/lib/action_cable/server/base.rb +4 -2
- data/lib/action_cable/server/broadcasting.rb +2 -0
- data/lib/action_cable/server/configuration.rb +18 -3
- data/lib/action_cable/server/connections.rb +2 -0
- data/lib/action_cable/server/worker.rb +2 -0
- data/lib/action_cable/server/worker/active_record_connection_management.rb +2 -0
- data/lib/action_cable/subscription_adapter.rb +2 -0
- data/lib/action_cable/subscription_adapter/async.rb +2 -0
- data/lib/action_cable/subscription_adapter/base.rb +2 -0
- data/lib/action_cable/subscription_adapter/channel_prefix.rb +2 -0
- data/lib/action_cable/subscription_adapter/inline.rb +2 -0
- data/lib/action_cable/subscription_adapter/postgresql.rb +11 -4
- data/lib/action_cable/subscription_adapter/redis.rb +6 -2
- data/lib/action_cable/subscription_adapter/subscriber_map.rb +2 -0
- data/lib/action_cable/version.rb +2 -0
- data/lib/rails/generators/channel/channel_generator.rb +3 -1
- data/lib/rails/generators/channel/templates/application_cable/{channel.rb → channel.rb.tt} +0 -0
- data/lib/rails/generators/channel/templates/application_cable/{connection.rb → connection.rb.tt} +0 -0
- data/lib/rails/generators/channel/templates/assets/{cable.js → cable.js.tt} +0 -0
- data/lib/rails/generators/channel/templates/assets/{channel.coffee → channel.coffee.tt} +0 -0
- data/lib/rails/generators/channel/templates/assets/{channel.js → channel.js.tt} +0 -0
- data/lib/rails/generators/channel/templates/{channel.rb → channel.rb.tt} +0 -0
- metadata +16 -16
- data/lib/action_cable/subscription_adapter/evented_redis.rb +0 -87
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: ed48c1e1ecb731be5c0e82e9fb43dbc570691fac
|
|
4
|
+
data.tar.gz: 8970db0c55b8101b5d3c59e540539452e00bf253
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dbd9ca9c8f42675eced47398b225c439a824e73a922dce9859e501521b03ddb24245f7e98caae78ebfc04ddf8e3700e9d6bcae13140e31385f6f9a94dcc23984
|
|
7
|
+
data.tar.gz: c2dfa7939e3fbbb343db1e23016bc2ee1f7c52ef076c60034dd07f225f1daa0cd2746593d429de857444e35602e9526f66bf45c86dc2f243f1d22c76ca85030d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,118 +1,29 @@
|
|
|
1
|
-
## Rails 5.
|
|
1
|
+
## Rails 5.2.0.beta1 (November 27, 2017) ##
|
|
2
2
|
|
|
3
|
-
*
|
|
3
|
+
* Removed deprecated evented redis adapter.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
## Rails 5.1.6.2 (March 11, 2019) ##
|
|
7
|
-
|
|
8
|
-
* No changes.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
## Rails 5.1.6.1 (November 27, 2018) ##
|
|
12
|
-
|
|
13
|
-
* No changes.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
## Rails 5.1.6 (March 29, 2018) ##
|
|
17
|
-
|
|
18
|
-
* No changes.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
## Rails 5.1.5 (February 14, 2018) ##
|
|
5
|
+
*Rafael Mendonça França*
|
|
22
6
|
|
|
23
7
|
* Support redis-rb 4.0.
|
|
24
8
|
|
|
25
9
|
*Jeremy Daer*
|
|
26
10
|
|
|
11
|
+
* Hash long stream identifiers when using PostgreSQL adapter.
|
|
27
12
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
* No changes.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
## Rails 5.1.4.rc1 (August 24, 2017) ##
|
|
34
|
-
|
|
35
|
-
* No changes.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
## Rails 5.1.3 (August 03, 2017) ##
|
|
39
|
-
|
|
40
|
-
* No changes.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
## Rails 5.1.3.rc3 (July 31, 2017) ##
|
|
44
|
-
|
|
45
|
-
* No changes.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
## Rails 5.1.3.rc2 (July 25, 2017) ##
|
|
49
|
-
|
|
50
|
-
* No changes.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
## Rails 5.1.3.rc1 (July 19, 2017) ##
|
|
54
|
-
|
|
55
|
-
* No changes.
|
|
13
|
+
PostgreSQL has a limit on identifiers length (63 chars, [docs](https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS)).
|
|
14
|
+
Provided fix minifies identifiers longer than 63 chars by hashing them with SHA1.
|
|
56
15
|
|
|
57
|
-
|
|
58
|
-
## Rails 5.1.2 (June 26, 2017) ##
|
|
59
|
-
|
|
60
|
-
* No changes.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
## Rails 5.1.1 (May 12, 2017) ##
|
|
64
|
-
|
|
65
|
-
* No changes.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
## Rails 5.1.0 (April 27, 2017) ##
|
|
69
|
-
|
|
70
|
-
* ActionCable socket errors are now logged to the console
|
|
71
|
-
|
|
72
|
-
Previously any socket errors were ignored and this made it hard to diagnose socket issues (e.g. as discussed in #28362).
|
|
73
|
-
|
|
74
|
-
*Edward Poot*
|
|
75
|
-
|
|
76
|
-
* Redis subscription adapters now support `channel_prefix` option in `cable.yml`
|
|
77
|
-
|
|
78
|
-
Avoids channel name collisions when multiple apps use the same Redis server.
|
|
79
|
-
|
|
80
|
-
*Chad Ingram*
|
|
81
|
-
|
|
82
|
-
* Permit same-origin connections by default.
|
|
83
|
-
|
|
84
|
-
Added new option `config.action_cable.allow_same_origin_as_host = false`
|
|
85
|
-
to disable this behaviour.
|
|
86
|
-
|
|
87
|
-
*Dávid Halász*, *Matthew Draper*
|
|
88
|
-
|
|
89
|
-
* Prevent race where the client could receive and act upon a
|
|
90
|
-
subscription confirmation before the channel's `subscribed` method
|
|
91
|
-
completed.
|
|
92
|
-
|
|
93
|
-
Fixes #25381.
|
|
16
|
+
Fixes #28751.
|
|
94
17
|
|
|
95
18
|
*Vladimir Dementyev*
|
|
96
19
|
|
|
97
|
-
*
|
|
98
|
-
that could be doing more useful things.
|
|
99
|
-
|
|
100
|
-
*Matthew Draper*, *Tinco Andringa*
|
|
101
|
-
|
|
102
|
-
* Protect against concurrent writes to a WebSocket connection from
|
|
103
|
-
multiple threads; the underlying OS write is not always threadsafe.
|
|
104
|
-
|
|
105
|
-
*Tinco Andringa*
|
|
106
|
-
|
|
107
|
-
* Add `ActiveSupport::Notifications` hook to `Broadcaster#broadcast`.
|
|
108
|
-
|
|
109
|
-
*Matthew Wear*
|
|
110
|
-
|
|
111
|
-
* Close hijacked socket when connection is shut down.
|
|
112
|
-
|
|
113
|
-
Fixes #25613.
|
|
20
|
+
* Action Cable's `redis` adapter allows for other common redis-rb options (`host`, `port`, `db`, `password`) in cable.yml.
|
|
114
21
|
|
|
115
|
-
|
|
22
|
+
Previously, it accepts only a [redis:// url](https://www.iana.org/assignments/uri-schemes/prov/redis) as an option.
|
|
23
|
+
While we can add all of these options to the `url` itself, it is not explicitly documented. This alternative setup
|
|
24
|
+
is shown as the first example in the [Redis rubygem](https://github.com/redis/redis-rb#getting-started), which
|
|
25
|
+
makes this set of options as sensible as using just the `url`.
|
|
116
26
|
|
|
27
|
+
*Marc Rendl Ignacio*
|
|
117
28
|
|
|
118
|
-
Please check [5-
|
|
29
|
+
Please check [5-1-stable](https://github.com/rails/rails/blob/5-1-stable/actioncable/CHANGELOG.md) for previous changes.
|
data/README.md
CHANGED
|
@@ -53,7 +53,7 @@ module ApplicationCable
|
|
|
53
53
|
|
|
54
54
|
private
|
|
55
55
|
def find_verified_user
|
|
56
|
-
if verified_user = User.find_by(id: cookies.
|
|
56
|
+
if verified_user = User.find_by(id: cookies.encrypted[:user_id])
|
|
57
57
|
verified_user
|
|
58
58
|
else
|
|
59
59
|
reject_unauthorized_connection
|
|
@@ -409,7 +409,7 @@ application. The recommended basic setup is as follows:
|
|
|
409
409
|
|
|
410
410
|
```ruby
|
|
411
411
|
# cable/config.ru
|
|
412
|
-
|
|
412
|
+
require_relative '../config/environment'
|
|
413
413
|
Rails.application.eager_load!
|
|
414
414
|
|
|
415
415
|
run ActionCable.server
|
|
@@ -446,7 +446,7 @@ The WebSocket server doesn't have access to the session, but it has access to th
|
|
|
446
446
|
|
|
447
447
|
## Dependencies
|
|
448
448
|
|
|
449
|
-
Action Cable provides a subscription adapter interface to process its pubsub internals. By default, asynchronous, inline, PostgreSQL,
|
|
449
|
+
Action Cable provides a subscription adapter interface to process its pubsub internals. By default, asynchronous, inline, PostgreSQL, and Redis adapters are included. The default adapter in new Rails applications is the asynchronous (`async`) adapter. To create your own adapter, you can look at `ActionCable::SubscriptionAdapter::Base` for all methods that must be implemented, and any of the adapters included within Action Cable as example implementations.
|
|
450
450
|
|
|
451
451
|
The Ruby side of things is built on top of [websocket-driver](https://github.com/faye/websocket-driver-ruby), [nio4r](https://github.com/celluloid/nio4r), and [concurrent-ruby](https://github.com/ruby-concurrency/concurrent-ruby).
|
|
452
452
|
|
|
@@ -454,9 +454,9 @@ The Ruby side of things is built on top of [websocket-driver](https://github.com
|
|
|
454
454
|
## Deployment
|
|
455
455
|
|
|
456
456
|
Action Cable is powered by a combination of WebSockets and threads. All of the
|
|
457
|
-
connection management is handled internally by utilizing Ruby
|
|
457
|
+
connection management is handled internally by utilizing Ruby's native thread
|
|
458
458
|
support, which means you can use all your regular Rails models with no problems
|
|
459
|
-
as long as you haven
|
|
459
|
+
as long as you haven't committed any thread-safety sins.
|
|
460
460
|
|
|
461
461
|
The Action Cable server does _not_ need to be a multi-threaded application server.
|
|
462
462
|
This is because Action Cable uses the [Rack socket hijacking API](http://www.rubydoc.info/github/rack/rack/file/SPEC#Hijacking)
|
|
@@ -549,7 +549,7 @@ Source code can be downloaded as part of the Rails project on GitHub
|
|
|
549
549
|
|
|
550
550
|
Action Cable is released under the MIT license:
|
|
551
551
|
|
|
552
|
-
*
|
|
552
|
+
* https://opensource.org/licenses/MIT
|
|
553
553
|
|
|
554
554
|
|
|
555
555
|
## Support
|
data/lib/action_cable.rb
CHANGED
data/lib/action_cable/channel.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "set"
|
|
2
4
|
|
|
3
5
|
module ActionCable
|
|
@@ -205,7 +207,9 @@ module ActionCable
|
|
|
205
207
|
# Transmit a hash of data to the subscriber. The hash will automatically be wrapped in a JSON envelope with
|
|
206
208
|
# the proper channel identifier marked as the recipient.
|
|
207
209
|
def transmit(data, via: nil) # :doc:
|
|
208
|
-
|
|
210
|
+
status = "#{self.class.name} transmitting #{data.inspect.truncate(300)}"
|
|
211
|
+
status += " (via #{via})" if via
|
|
212
|
+
logger.debug(status)
|
|
209
213
|
|
|
210
214
|
payload = { channel_class: self.class.name, data: data, via: via }
|
|
211
215
|
ActiveSupport::Notifications.instrument("transmit.action_cable", payload) do
|
|
@@ -266,7 +270,7 @@ module ActionCable
|
|
|
266
270
|
end
|
|
267
271
|
|
|
268
272
|
def action_signature(action, data)
|
|
269
|
-
"#{self.class.name}##{action}".tap do |signature|
|
|
273
|
+
"#{self.class.name}##{action}".dup.tap do |signature|
|
|
270
274
|
if (arguments = data.except("action")).any?
|
|
271
275
|
signature << "(#{arguments.inspect})"
|
|
272
276
|
end
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionCable
|
|
2
4
|
module Channel
|
|
3
5
|
module PeriodicTimers
|
|
4
6
|
extend ActiveSupport::Concern
|
|
5
7
|
|
|
6
8
|
included do
|
|
7
|
-
class_attribute :periodic_timers, instance_reader: false
|
|
8
|
-
self.periodic_timers = []
|
|
9
|
+
class_attribute :periodic_timers, instance_reader: false, default: []
|
|
9
10
|
|
|
10
11
|
after_subscribe :start_periodic_timers
|
|
11
12
|
after_unsubscribe :stop_periodic_timers
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "action_dispatch"
|
|
2
4
|
|
|
3
5
|
module ActionCable
|
|
@@ -24,7 +26,7 @@ module ActionCable
|
|
|
24
26
|
#
|
|
25
27
|
# private
|
|
26
28
|
# def find_verified_user
|
|
27
|
-
# User.find_by_identity(cookies.
|
|
29
|
+
# User.find_by_identity(cookies.encrypted[:identity_id]) ||
|
|
28
30
|
# reject_unauthorized_connection
|
|
29
31
|
# end
|
|
30
32
|
# end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "websocket/driver"
|
|
2
4
|
|
|
3
5
|
module ActionCable
|
|
@@ -19,7 +21,7 @@ module ActionCable
|
|
|
19
21
|
return true if env["HTTP_X_FORWARDED_PROTO"] == "https"
|
|
20
22
|
return true if env["rack.url_scheme"] == "https"
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
false
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
CONNECTING = 0
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "set"
|
|
2
4
|
|
|
3
5
|
module ActionCable
|
|
@@ -6,8 +8,7 @@ module ActionCable
|
|
|
6
8
|
extend ActiveSupport::Concern
|
|
7
9
|
|
|
8
10
|
included do
|
|
9
|
-
class_attribute :identifiers
|
|
10
|
-
self.identifiers = Set.new
|
|
11
|
+
class_attribute :identifiers, default: Set.new
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
class_methods do
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "active_support/core_ext/hash/indifferent_access"
|
|
2
4
|
|
|
3
5
|
module ActionCable
|
|
@@ -41,7 +43,7 @@ module ActionCable
|
|
|
41
43
|
|
|
42
44
|
def remove(data)
|
|
43
45
|
logger.info "Unsubscribing from channel: #{data['identifier']}"
|
|
44
|
-
remove_subscription
|
|
46
|
+
remove_subscription find(data)
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
def remove_subscription(subscription)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "websocket/driver"
|
|
2
4
|
|
|
3
5
|
module ActionCable
|
|
4
6
|
module Connection
|
|
5
7
|
# Wrap the real socket to minimize the externally-presented API
|
|
6
|
-
class WebSocket
|
|
8
|
+
class WebSocket # :nodoc:
|
|
7
9
|
def initialize(env, event_target, event_loop, protocols: ActionCable::INTERNAL[:protocols])
|
|
8
10
|
@websocket = ::WebSocket::Driver.websocket?(env) ? ClientSocket.new(env, event_target, event_loop, protocols) : nil
|
|
9
11
|
end
|
data/lib/action_cable/engine.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionCable
|
|
2
4
|
# Returns the version of the currently loaded Action Cable as a <tt>Gem::Version</tt>.
|
|
3
5
|
def self.gem_version
|
|
@@ -6,9 +8,9 @@ module ActionCable
|
|
|
6
8
|
|
|
7
9
|
module VERSION
|
|
8
10
|
MAJOR = 5
|
|
9
|
-
MINOR =
|
|
10
|
-
TINY =
|
|
11
|
-
PRE =
|
|
11
|
+
MINOR = 2
|
|
12
|
+
TINY = 0
|
|
13
|
+
PRE = "beta1"
|
|
12
14
|
|
|
13
15
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
|
14
16
|
end
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/module/redefine_method"
|
|
4
|
+
|
|
1
5
|
module ActionCable
|
|
2
6
|
# If you need to disconnect a given connection, you can go through the
|
|
3
7
|
# RemoteConnections. You can find the connections you're looking for by
|
|
@@ -45,13 +49,14 @@ module ActionCable
|
|
|
45
49
|
end
|
|
46
50
|
|
|
47
51
|
# Returns all the identifiers that were applied to this connection.
|
|
48
|
-
|
|
52
|
+
redefine_method :identifiers do
|
|
49
53
|
server.connection_identifiers
|
|
50
54
|
end
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
protected
|
|
53
57
|
attr_reader :server
|
|
54
58
|
|
|
59
|
+
private
|
|
55
60
|
def set_identifier_instance_vars(ids)
|
|
56
61
|
raise InvalidIdentifiersError unless valid_identifiers?(ids)
|
|
57
62
|
ids.each { |k, v| instance_variable_set("@#{k}", v) }
|
data/lib/action_cable/server.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "monitor"
|
|
2
4
|
|
|
3
5
|
module ActionCable
|
|
@@ -10,7 +12,7 @@ module ActionCable
|
|
|
10
12
|
include ActionCable::Server::Broadcasting
|
|
11
13
|
include ActionCable::Server::Connections
|
|
12
14
|
|
|
13
|
-
cattr_accessor
|
|
15
|
+
cattr_accessor :config, instance_accessor: true, default: ActionCable::Server::Configuration.new
|
|
14
16
|
|
|
15
17
|
def self.logger; config.logger; end
|
|
16
18
|
delegate :logger, to: :config
|
|
@@ -28,7 +30,7 @@ module ActionCable
|
|
|
28
30
|
config.connection_class.call.new(self, env).process
|
|
29
31
|
end
|
|
30
32
|
|
|
31
|
-
# Disconnect all the connections identified by
|
|
33
|
+
# Disconnect all the connections identified by +identifiers+ on this server or any others via RemoteConnections.
|
|
32
34
|
def disconnect(identifiers)
|
|
33
35
|
remote_connections.where(identifiers).disconnect
|
|
34
36
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ActionCable
|
|
2
4
|
module Server
|
|
3
5
|
# An instance of this configuration object is available via ActionCable.server.config, which allows you to tweak Action Cable configuration
|
|
@@ -23,13 +25,26 @@ module ActionCable
|
|
|
23
25
|
# Also makes sure proper dependencies are required.
|
|
24
26
|
def pubsub_adapter
|
|
25
27
|
adapter = (cable.fetch("adapter") { "redis" })
|
|
28
|
+
|
|
29
|
+
# Require the adapter itself and give useful feedback about
|
|
30
|
+
# 1. Missing adapter gems and
|
|
31
|
+
# 2. Adapter gems' missing dependencies.
|
|
26
32
|
path_to_adapter = "action_cable/subscription_adapter/#{adapter}"
|
|
27
33
|
begin
|
|
28
34
|
require path_to_adapter
|
|
29
|
-
rescue Gem::LoadError => e
|
|
30
|
-
raise Gem::LoadError, "Specified '#{adapter}' for Action Cable pubsub adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile (and ensure its version is at the minimum required by Action Cable)."
|
|
31
35
|
rescue LoadError => e
|
|
32
|
-
|
|
36
|
+
# We couldn't require the adapter itself. Raise an exception that
|
|
37
|
+
# points out config typos and missing gems.
|
|
38
|
+
if e.path == path_to_adapter
|
|
39
|
+
# We can assume that a non-builtin adapter was specified, so it's
|
|
40
|
+
# either misspelled or missing from Gemfile.
|
|
41
|
+
raise e.class, "Could not load the '#{adapter}' Action Cable pubsub adapter. Ensure that the adapter is spelled correctly in config/cable.yml and that you've added the necessary adapter gem to your Gemfile.", e.backtrace
|
|
42
|
+
|
|
43
|
+
# Bubbled up from the adapter require. Prefix the exception message
|
|
44
|
+
# with some guidance about how to address it and reraise.
|
|
45
|
+
else
|
|
46
|
+
raise e.class, "Error loading the '#{adapter}' Action Cable pubsub adapter. Missing a gem it depends on? #{e.message}", e.backtrace
|
|
47
|
+
end
|
|
33
48
|
end
|
|
34
49
|
|
|
35
50
|
adapter = adapter.camelize
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
gem "pg", "~> 0.18"
|
|
2
4
|
require "pg"
|
|
3
5
|
require "thread"
|
|
6
|
+
require "digest/sha1"
|
|
4
7
|
|
|
5
8
|
module ActionCable
|
|
6
9
|
module SubscriptionAdapter
|
|
@@ -12,16 +15,16 @@ module ActionCable
|
|
|
12
15
|
|
|
13
16
|
def broadcast(channel, payload)
|
|
14
17
|
with_connection do |pg_conn|
|
|
15
|
-
pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel)}, '#{pg_conn.escape_string(payload)}'")
|
|
18
|
+
pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel_identifier(channel))}, '#{pg_conn.escape_string(payload)}'")
|
|
16
19
|
end
|
|
17
20
|
end
|
|
18
21
|
|
|
19
22
|
def subscribe(channel, callback, success_callback = nil)
|
|
20
|
-
listener.add_subscriber(channel, callback, success_callback)
|
|
23
|
+
listener.add_subscriber(channel_identifier(channel), callback, success_callback)
|
|
21
24
|
end
|
|
22
25
|
|
|
23
26
|
def unsubscribe(channel, callback)
|
|
24
|
-
listener.remove_subscriber(channel, callback)
|
|
27
|
+
listener.remove_subscriber(channel_identifier(channel), callback)
|
|
25
28
|
end
|
|
26
29
|
|
|
27
30
|
def shutdown
|
|
@@ -41,6 +44,10 @@ module ActionCable
|
|
|
41
44
|
end
|
|
42
45
|
|
|
43
46
|
private
|
|
47
|
+
def channel_identifier(channel)
|
|
48
|
+
channel.size > 63 ? Digest::SHA1.hexdigest(channel) : channel
|
|
49
|
+
end
|
|
50
|
+
|
|
44
51
|
def listener
|
|
45
52
|
@listener || @server.mutex.synchronize { @listener ||= Listener.new(self, @server.event_loop) }
|
|
46
53
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "thread"
|
|
2
4
|
|
|
3
5
|
gem "redis", ">= 3", "< 5"
|
|
@@ -8,9 +10,11 @@ module ActionCable
|
|
|
8
10
|
class Redis < Base # :nodoc:
|
|
9
11
|
prepend ChannelPrefix
|
|
10
12
|
|
|
11
|
-
# Overwrite this factory method for
|
|
13
|
+
# Overwrite this factory method for Redis connections if you want to use a different Redis library than the redis gem.
|
|
12
14
|
# This is needed, for example, when using Makara proxies for distributed Redis.
|
|
13
|
-
cattr_accessor
|
|
15
|
+
cattr_accessor :redis_connector, default: ->(config) do
|
|
16
|
+
::Redis.new(config.slice(:url, :host, :port, :db, :password))
|
|
17
|
+
end
|
|
14
18
|
|
|
15
19
|
def initialize(*)
|
|
16
20
|
super
|
data/lib/action_cable/version.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Rails
|
|
2
4
|
module Generators
|
|
3
5
|
class ChannelGenerator < NamedBase
|
|
4
|
-
source_root File.expand_path("
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
5
7
|
|
|
6
8
|
argument :actions, type: :array, default: [], banner: "method method"
|
|
7
9
|
|
|
File without changes
|
data/lib/rails/generators/channel/templates/application_cable/{connection.rb → connection.rb.tt}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
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.
|
|
4
|
+
version: 5.2.0.beta1
|
|
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:
|
|
12
|
+
date: 2017-11-27 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: actionpack
|
|
@@ -17,14 +17,14 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - '='
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version: 5.
|
|
20
|
+
version: 5.2.0.beta1
|
|
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.
|
|
27
|
+
version: 5.2.0.beta1
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
|
29
29
|
name: nio4r
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -100,7 +100,6 @@ files:
|
|
|
100
100
|
- lib/action_cable/subscription_adapter/async.rb
|
|
101
101
|
- lib/action_cable/subscription_adapter/base.rb
|
|
102
102
|
- lib/action_cable/subscription_adapter/channel_prefix.rb
|
|
103
|
-
- lib/action_cable/subscription_adapter/evented_redis.rb
|
|
104
103
|
- lib/action_cable/subscription_adapter/inline.rb
|
|
105
104
|
- lib/action_cable/subscription_adapter/postgresql.rb
|
|
106
105
|
- lib/action_cable/subscription_adapter/redis.rb
|
|
@@ -109,18 +108,18 @@ files:
|
|
|
109
108
|
- lib/assets/compiled/action_cable.js
|
|
110
109
|
- lib/rails/generators/channel/USAGE
|
|
111
110
|
- lib/rails/generators/channel/channel_generator.rb
|
|
112
|
-
- lib/rails/generators/channel/templates/application_cable/channel.rb
|
|
113
|
-
- lib/rails/generators/channel/templates/application_cable/connection.rb
|
|
114
|
-
- lib/rails/generators/channel/templates/assets/cable.js
|
|
115
|
-
- lib/rails/generators/channel/templates/assets/channel.coffee
|
|
116
|
-
- lib/rails/generators/channel/templates/assets/channel.js
|
|
117
|
-
- lib/rails/generators/channel/templates/channel.rb
|
|
111
|
+
- lib/rails/generators/channel/templates/application_cable/channel.rb.tt
|
|
112
|
+
- lib/rails/generators/channel/templates/application_cable/connection.rb.tt
|
|
113
|
+
- lib/rails/generators/channel/templates/assets/cable.js.tt
|
|
114
|
+
- lib/rails/generators/channel/templates/assets/channel.coffee.tt
|
|
115
|
+
- lib/rails/generators/channel/templates/assets/channel.js.tt
|
|
116
|
+
- lib/rails/generators/channel/templates/channel.rb.tt
|
|
118
117
|
homepage: http://rubyonrails.org
|
|
119
118
|
licenses:
|
|
120
119
|
- MIT
|
|
121
120
|
metadata:
|
|
122
|
-
source_code_uri: https://github.com/rails/rails/tree/v5.
|
|
123
|
-
changelog_uri: https://github.com/rails/rails/blob/v5.
|
|
121
|
+
source_code_uri: https://github.com/rails/rails/tree/v5.2.0.beta1/actioncable
|
|
122
|
+
changelog_uri: https://github.com/rails/rails/blob/v5.2.0.beta1/actioncable/CHANGELOG.md
|
|
124
123
|
post_install_message:
|
|
125
124
|
rdoc_options: []
|
|
126
125
|
require_paths:
|
|
@@ -132,11 +131,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
132
131
|
version: 2.2.2
|
|
133
132
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
134
133
|
requirements:
|
|
135
|
-
- - "
|
|
134
|
+
- - ">"
|
|
136
135
|
- !ruby/object:Gem::Version
|
|
137
|
-
version:
|
|
136
|
+
version: 1.3.1
|
|
138
137
|
requirements: []
|
|
139
|
-
|
|
138
|
+
rubyforge_project:
|
|
139
|
+
rubygems_version: 2.6.12
|
|
140
140
|
signing_key:
|
|
141
141
|
specification_version: 4
|
|
142
142
|
summary: WebSocket framework for Rails.
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
require "thread"
|
|
2
|
-
|
|
3
|
-
gem "em-hiredis", "~> 0.3.0"
|
|
4
|
-
gem "redis", ">= 3", "< 5"
|
|
5
|
-
require "em-hiredis"
|
|
6
|
-
require "redis"
|
|
7
|
-
|
|
8
|
-
EventMachine.epoll if EventMachine.epoll?
|
|
9
|
-
EventMachine.kqueue if EventMachine.kqueue?
|
|
10
|
-
|
|
11
|
-
module ActionCable
|
|
12
|
-
module SubscriptionAdapter
|
|
13
|
-
class EventedRedis < Base # :nodoc:
|
|
14
|
-
prepend ChannelPrefix
|
|
15
|
-
|
|
16
|
-
@@mutex = Mutex.new
|
|
17
|
-
|
|
18
|
-
# Overwrite this factory method for EventMachine Redis connections if you want to use a different Redis connection library than EM::Hiredis.
|
|
19
|
-
# This is needed, for example, when using Makara proxies for distributed Redis.
|
|
20
|
-
cattr_accessor(:em_redis_connector) { ->(config) { EM::Hiredis.connect(config[:url]) } }
|
|
21
|
-
|
|
22
|
-
# Overwrite this factory method for Redis connections if you want to use a different Redis connection library than Redis.
|
|
23
|
-
# This is needed, for example, when using Makara proxies for distributed Redis.
|
|
24
|
-
cattr_accessor(:redis_connector) { ->(config) { ::Redis.new(url: config[:url]) } }
|
|
25
|
-
|
|
26
|
-
def initialize(*)
|
|
27
|
-
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
|
28
|
-
The "evented_redis" subscription adapter is deprecated and
|
|
29
|
-
will be removed in Rails 5.2. Please use the "redis" adapter
|
|
30
|
-
instead.
|
|
31
|
-
MSG
|
|
32
|
-
|
|
33
|
-
super
|
|
34
|
-
@redis_connection_for_broadcasts = @redis_connection_for_subscriptions = nil
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def broadcast(channel, payload)
|
|
38
|
-
redis_connection_for_broadcasts.publish(channel, payload)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def subscribe(channel, message_callback, success_callback = nil)
|
|
42
|
-
redis_connection_for_subscriptions.pubsub.subscribe(channel, &message_callback).tap do |result|
|
|
43
|
-
result.callback { |reply| success_callback.call } if success_callback
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def unsubscribe(channel, message_callback)
|
|
48
|
-
redis_connection_for_subscriptions.pubsub.unsubscribe_proc(channel, message_callback)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def shutdown
|
|
52
|
-
redis_connection_for_subscriptions.pubsub.close_connection
|
|
53
|
-
@redis_connection_for_subscriptions = nil
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
private
|
|
57
|
-
def redis_connection_for_subscriptions
|
|
58
|
-
ensure_reactor_running
|
|
59
|
-
@redis_connection_for_subscriptions || @server.mutex.synchronize do
|
|
60
|
-
@redis_connection_for_subscriptions ||= self.class.em_redis_connector.call(@server.config.cable).tap do |redis|
|
|
61
|
-
redis.on(:reconnect_failed) do
|
|
62
|
-
@logger.error "[ActionCable] Redis reconnect failed."
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
redis.on(:failed) do
|
|
66
|
-
@logger.error "[ActionCable] Redis connection has failed."
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def redis_connection_for_broadcasts
|
|
73
|
-
@redis_connection_for_broadcasts || @server.mutex.synchronize do
|
|
74
|
-
@redis_connection_for_broadcasts ||= self.class.redis_connector.call(@server.config.cable)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def ensure_reactor_running
|
|
79
|
-
return if EventMachine.reactor_running? && EventMachine.reactor_thread
|
|
80
|
-
@@mutex.synchronize do
|
|
81
|
-
Thread.new { EventMachine.run } unless EventMachine.reactor_running?
|
|
82
|
-
Thread.pass until EventMachine.reactor_running? && EventMachine.reactor_thread
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|