actioncable 5.1.7 → 5.2.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +14 -103
  3. data/README.md +6 -6
  4. data/lib/action_cable.rb +2 -0
  5. data/lib/action_cable/channel.rb +2 -0
  6. data/lib/action_cable/channel/base.rb +6 -2
  7. data/lib/action_cable/channel/broadcasting.rb +2 -0
  8. data/lib/action_cable/channel/callbacks.rb +2 -0
  9. data/lib/action_cable/channel/naming.rb +2 -0
  10. data/lib/action_cable/channel/periodic_timers.rb +3 -2
  11. data/lib/action_cable/channel/streams.rb +2 -0
  12. data/lib/action_cable/connection.rb +2 -0
  13. data/lib/action_cable/connection/authorization.rb +2 -0
  14. data/lib/action_cable/connection/base.rb +3 -1
  15. data/lib/action_cable/connection/client_socket.rb +3 -1
  16. data/lib/action_cable/connection/identification.rb +3 -2
  17. data/lib/action_cable/connection/internal_channel.rb +2 -0
  18. data/lib/action_cable/connection/message_buffer.rb +2 -0
  19. data/lib/action_cable/connection/stream.rb +2 -0
  20. data/lib/action_cable/connection/stream_event_loop.rb +2 -0
  21. data/lib/action_cable/connection/subscriptions.rb +3 -1
  22. data/lib/action_cable/connection/tagged_logger_proxy.rb +2 -0
  23. data/lib/action_cable/connection/web_socket.rb +3 -1
  24. data/lib/action_cable/engine.rb +2 -0
  25. data/lib/action_cable/gem_version.rb +5 -3
  26. data/lib/action_cable/helpers/action_cable_helper.rb +2 -0
  27. data/lib/action_cable/remote_connections.rb +7 -2
  28. data/lib/action_cable/server.rb +2 -0
  29. data/lib/action_cable/server/base.rb +4 -2
  30. data/lib/action_cable/server/broadcasting.rb +2 -0
  31. data/lib/action_cable/server/configuration.rb +18 -3
  32. data/lib/action_cable/server/connections.rb +2 -0
  33. data/lib/action_cable/server/worker.rb +2 -0
  34. data/lib/action_cable/server/worker/active_record_connection_management.rb +2 -0
  35. data/lib/action_cable/subscription_adapter.rb +2 -0
  36. data/lib/action_cable/subscription_adapter/async.rb +2 -0
  37. data/lib/action_cable/subscription_adapter/base.rb +2 -0
  38. data/lib/action_cable/subscription_adapter/channel_prefix.rb +2 -0
  39. data/lib/action_cable/subscription_adapter/inline.rb +2 -0
  40. data/lib/action_cable/subscription_adapter/postgresql.rb +11 -4
  41. data/lib/action_cable/subscription_adapter/redis.rb +6 -2
  42. data/lib/action_cable/subscription_adapter/subscriber_map.rb +2 -0
  43. data/lib/action_cable/version.rb +2 -0
  44. data/lib/rails/generators/channel/channel_generator.rb +3 -1
  45. data/lib/rails/generators/channel/templates/application_cable/{channel.rb → channel.rb.tt} +0 -0
  46. data/lib/rails/generators/channel/templates/application_cable/{connection.rb → connection.rb.tt} +0 -0
  47. data/lib/rails/generators/channel/templates/assets/{cable.js → cable.js.tt} +0 -0
  48. data/lib/rails/generators/channel/templates/assets/{channel.coffee → channel.coffee.tt} +0 -0
  49. data/lib/rails/generators/channel/templates/assets/{channel.js → channel.js.tt} +0 -0
  50. data/lib/rails/generators/channel/templates/{channel.rb → channel.rb.tt} +0 -0
  51. metadata +16 -16
  52. data/lib/action_cable/subscription_adapter/evented_redis.rb +0 -87
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 55650fcf9d6b19dc5233504a8e07d9439208190100672db6c7776142cd807e15
4
- data.tar.gz: 7653a1421420d545bd92012acbbe55182b56d62eddc0c3095d7b4660da47a7a4
2
+ SHA1:
3
+ metadata.gz: ed48c1e1ecb731be5c0e82e9fb43dbc570691fac
4
+ data.tar.gz: 8970db0c55b8101b5d3c59e540539452e00bf253
5
5
  SHA512:
6
- metadata.gz: 5e48dcd6762bce6425a2df18ddc9578d2930fa07eca5ae7078f7c7572132ea589d8c6c1311ea90fad0cbcf675771595309d88136c7015d0e293d4cefe23c167c
7
- data.tar.gz: 1a636b5b05b1e4607977158e0b15c10855159007d35f18d3b02320b41aad251b6db4bafa68f5dac7525e1ec08755350bead9553da3bf320a40bc55664700ccda
6
+ metadata.gz: dbd9ca9c8f42675eced47398b225c439a824e73a922dce9859e501521b03ddb24245f7e98caae78ebfc04ddf8e3700e9d6bcae13140e31385f6f9a94dcc23984
7
+ data.tar.gz: c2dfa7939e3fbbb343db1e23016bc2ee1f7c52ef076c60034dd07f225f1daa0cd2746593d429de857444e35602e9526f66bf45c86dc2f243f1d22c76ca85030d
data/CHANGELOG.md CHANGED
@@ -1,118 +1,29 @@
1
- ## Rails 5.1.7 (March 27, 2019) ##
1
+ ## Rails 5.2.0.beta1 (November 27, 2017) ##
2
2
 
3
- * No changes.
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
- ## Rails 5.1.4 (September 07, 2017) ##
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
- * Buffer now writes to WebSocket connections, to avoid blocking threads
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
- *Tinco Andringa*
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-0-stable](https://github.com/rails/rails/blob/5-0-stable/actioncable/CHANGELOG.md) for previous changes.
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.signed[:user_id])
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
- require ::File.expand_path('../../config/environment', __FILE__)
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, evented Redis, and non-evented 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.
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 Rubys native thread
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 havent committed any thread-safety sins.
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
- * http://www.opensource.org/licenses/MIT
552
+ * https://opensource.org/licenses/MIT
553
553
 
554
554
 
555
555
  ## Support
data/lib/action_cable.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  #--
2
4
  # Copyright (c) 2015-2017 Basecamp, LLC
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Channel
3
5
  extend ActiveSupport::Autoload
@@ -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
- logger.debug "#{self.class.name} transmitting #{data.inspect.truncate(300)}".tap { |m| m << " (via #{via})" if via }
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/object/to_param"
2
4
 
3
5
  module ActionCable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/callbacks"
2
4
 
3
5
  module ActionCable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Channel
3
5
  module Naming
@@ -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
  module ActionCable
2
4
  module Channel
3
5
  # Streams allow channels to route broadcastings to the subscriber. A broadcasting is, as discussed elsewhere, a pubsub queue where any data
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Connection
3
5
  extend ActiveSupport::Autoload
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Connection
3
5
  module Authorization
@@ -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.signed[:identity_id]) ||
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
- return false
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
  module ActionCable
2
4
  module Connection
3
5
  # Makes it possible for the RemoteConnection to disconnect a specific connection.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Connection
3
5
  # Allows us to buffer messages received from the WebSocket before the Connection has been fully initialized, and is ready to receive them.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "thread"
2
4
 
3
5
  module ActionCable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "nio"
2
4
  require "thread"
3
5
 
@@ -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 subscriptions[data["identifier"]]
46
+ remove_subscription find(data)
45
47
  end
46
48
 
47
49
  def remove_subscription(subscription)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Connection
3
5
  # Allows the use of per-connection tags against the server logger. This wouldn't work using the traditional
@@ -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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "rails"
2
4
  require "action_cable"
3
5
  require "action_cable/helpers/action_cable_helper"
@@ -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 = 1
10
- TINY = 7
11
- PRE = nil
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,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Helpers
3
5
  module ActionCableHelper
@@ -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
- def identifiers
52
+ redefine_method :identifiers do
49
53
  server.connection_identifiers
50
54
  end
51
55
 
52
- private
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) }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Server
3
5
  extend ActiveSupport::Autoload
@@ -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(:config, instance_accessor: true) { ActionCable::Server::Configuration.new }
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 `identifiers` on this server or any others via RemoteConnections.
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
  # Broadcasting is how other parts of your application can send messages to a channel's subscribers. As explained in Channel, most of the time, these
@@ -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
- raise LoadError, "Could not load '#{path_to_adapter}'. Make sure that the adapter in config/cable.yml is valid. If you use an adapter other than 'postgresql' or 'redis' add the necessary adapter gem to the Gemfile.", e.backtrace
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Server
3
5
  # Collection class for all the connections that have been established on this specific server. Remember, usually you'll run many Action Cable servers, so
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/callbacks"
2
4
  require "active_support/core_ext/module/attribute_accessors_per_thread"
3
5
  require "concurrent"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module Server
3
5
  class Worker
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module SubscriptionAdapter
3
5
  extend ActiveSupport::Autoload
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "action_cable/subscription_adapter/inline"
2
4
 
3
5
  module ActionCable
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module SubscriptionAdapter
3
5
  class Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module SubscriptionAdapter
3
5
  module ChannelPrefix # :nodoc:
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module SubscriptionAdapter
3
5
  class Inline < Base # :nodoc:
@@ -1,6 +1,9 @@
1
- gem "pg", ">= 0.18", "< 2.0"
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 redis connections if you want to use a different Redis library than Redis.
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(:redis_connector) { ->(config) { ::Redis.new(url: config[:url]) } }
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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionCable
2
4
  module SubscriptionAdapter
3
5
  class SubscriberMap
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "gem_version"
2
4
 
3
5
  module ActionCable
@@ -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("../templates", __FILE__)
6
+ source_root File.expand_path("templates", __dir__)
5
7
 
6
8
  argument :actions, type: :array, default: [], banner: "method method"
7
9
 
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.1.7
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: 2019-03-28 00:00:00.000000000 Z
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.1.7
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.1.7
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.1.7/actioncable
123
- changelog_uri: https://github.com/rails/rails/blob/v5.1.7/actioncable/CHANGELOG.md
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: '0'
136
+ version: 1.3.1
138
137
  requirements: []
139
- rubygems_version: 3.0.1
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