actioncable 7.1.5.2 → 7.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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -171
  3. data/app/assets/javascripts/action_cable.js +3 -3
  4. data/app/assets/javascripts/actioncable.esm.js +3 -3
  5. data/app/assets/javascripts/actioncable.js +3 -3
  6. data/lib/action_cable/channel/base.rb +98 -86
  7. data/lib/action_cable/channel/broadcasting.rb +25 -18
  8. data/lib/action_cable/channel/callbacks.rb +27 -25
  9. data/lib/action_cable/channel/naming.rb +9 -8
  10. data/lib/action_cable/channel/periodic_timers.rb +7 -7
  11. data/lib/action_cable/channel/streams.rb +77 -64
  12. data/lib/action_cable/channel/test_case.rb +112 -86
  13. data/lib/action_cable/connection/authorization.rb +4 -1
  14. data/lib/action_cable/connection/base.rb +53 -38
  15. data/lib/action_cable/connection/callbacks.rb +20 -18
  16. data/lib/action_cable/connection/client_socket.rb +3 -1
  17. data/lib/action_cable/connection/identification.rb +9 -5
  18. data/lib/action_cable/connection/internal_channel.rb +5 -2
  19. data/lib/action_cable/connection/message_buffer.rb +4 -1
  20. data/lib/action_cable/connection/stream.rb +2 -0
  21. data/lib/action_cable/connection/stream_event_loop.rb +4 -3
  22. data/lib/action_cable/connection/subscriptions.rb +6 -3
  23. data/lib/action_cable/connection/tagged_logger_proxy.rb +7 -4
  24. data/lib/action_cable/connection/test_case.rb +66 -56
  25. data/lib/action_cable/connection/web_socket.rb +10 -8
  26. data/lib/action_cable/deprecator.rb +2 -0
  27. data/lib/action_cable/engine.rb +5 -3
  28. data/lib/action_cable/gem_version.rb +6 -4
  29. data/lib/action_cable/helpers/action_cable_helper.rb +21 -19
  30. data/lib/action_cable/remote_connections.rb +19 -16
  31. data/lib/action_cable/server/base.rb +27 -15
  32. data/lib/action_cable/server/broadcasting.rb +23 -17
  33. data/lib/action_cable/server/configuration.rb +17 -14
  34. data/lib/action_cable/server/connections.rb +11 -5
  35. data/lib/action_cable/server/worker/active_record_connection_management.rb +2 -0
  36. data/lib/action_cable/server/worker.rb +4 -2
  37. data/lib/action_cable/subscription_adapter/async.rb +2 -0
  38. data/lib/action_cable/subscription_adapter/base.rb +2 -0
  39. data/lib/action_cable/subscription_adapter/channel_prefix.rb +2 -0
  40. data/lib/action_cable/subscription_adapter/inline.rb +2 -0
  41. data/lib/action_cable/subscription_adapter/postgresql.rb +4 -2
  42. data/lib/action_cable/subscription_adapter/redis.rb +5 -2
  43. data/lib/action_cable/subscription_adapter/subscriber_map.rb +2 -0
  44. data/lib/action_cable/subscription_adapter/test.rb +8 -5
  45. data/lib/action_cable/test_case.rb +2 -0
  46. data/lib/action_cable/test_helper.rb +51 -48
  47. data/lib/action_cable/version.rb +3 -1
  48. data/lib/action_cable.rb +1 -0
  49. data/lib/rails/generators/channel/channel_generator.rb +4 -2
  50. data/lib/rails/generators/channel/templates/application_cable/channel.rb +2 -0
  51. data/lib/rails/generators/channel/templates/application_cable/connection.rb +2 -0
  52. data/lib/rails/generators/test_unit/channel_generator.rb +2 -0
  53. metadata +14 -11
@@ -1,11 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module Server
5
- # = Action Cable \Server \Connections
7
+ # # Action Cable Server Connections
6
8
  #
7
- # Collection class for all the connections that have been established on this specific server. Remember, usually you'll run many Action Cable servers, so
8
- # you can't use this collection as a full list of all of the connections established against your application. Instead, use RemoteConnections for that.
9
+ # Collection class for all the connections that have been established on this
10
+ # specific server. Remember, usually you'll run many Action Cable servers, so
11
+ # you can't use this collection as a full list of all of the connections
12
+ # established against your application. Instead, use RemoteConnections for that.
9
13
  module Connections # :nodoc:
10
14
  BEAT_INTERVAL = 3
11
15
 
@@ -21,8 +25,10 @@ module ActionCable
21
25
  connections.delete connection
22
26
  end
23
27
 
24
- # WebSocket connection implementations differ on when they'll mark a connection as stale. We basically never want a connection to go stale, as you
25
- # then can't rely on being able to communicate with the connection. To solve this, a 3 second heartbeat runs on all connections. If the beat fails, we automatically
28
+ # WebSocket connection implementations differ on when they'll mark a connection
29
+ # as stale. We basically never want a connection to go stale, as you then can't
30
+ # rely on being able to communicate with the connection. To solve this, a 3
31
+ # second heartbeat runs on all connections. If the beat fails, we automatically
26
32
  # disconnect.
27
33
  def setup_heartbeat_timer
28
34
  @heartbeat_timer ||= event_loop.timer(BEAT_INTERVAL) do
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module Server
5
7
  class Worker
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/callbacks"
4
6
  require "active_support/core_ext/module/attribute_accessors_per_thread"
5
7
  require "concurrent"
@@ -25,8 +27,8 @@ module ActionCable
25
27
  )
26
28
  end
27
29
 
28
- # Stop processing work: any work that has not already started
29
- # running will be discarded from the queue
30
+ # Stop processing work: any work that has not already started running will be
31
+ # discarded from the queue
30
32
  def halt
31
33
  @executor.shutdown
32
34
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module SubscriptionAdapter
5
7
  class Async < Inline # :nodoc:
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module SubscriptionAdapter
5
7
  class Base
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module SubscriptionAdapter
5
7
  module ChannelPrefix # :nodoc:
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module SubscriptionAdapter
5
7
  class Inline < Base # :nodoc:
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  gem "pg", "~> 1.1"
4
6
  require "pg"
5
7
  require "openssl"
@@ -34,8 +36,8 @@ module ActionCable
34
36
 
35
37
  def with_subscriptions_connection(&block) # :nodoc:
36
38
  ar_conn = ActiveRecord::Base.connection_pool.checkout.tap do |conn|
37
- # Action Cable is taking ownership over this database connection, and
38
- # will perform the necessary cleanup tasks
39
+ # Action Cable is taking ownership over this database connection, and will
40
+ # perform the necessary cleanup tasks
39
41
  ActiveRecord::Base.connection_pool.remove(conn)
40
42
  end
41
43
  pg_conn = ar_conn.raw_connection
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  gem "redis", ">= 4", "< 6"
4
6
  require "redis"
5
7
 
@@ -10,8 +12,9 @@ module ActionCable
10
12
  class Redis < Base # :nodoc:
11
13
  prepend ChannelPrefix
12
14
 
13
- # Overwrite this factory method for Redis connections if you want to use a different Redis library than the redis gem.
14
- # This is needed, for example, when using Makara proxies for distributed Redis.
15
+ # Overwrite this factory method for Redis connections if you want to use a
16
+ # different Redis library than the redis gem. This is needed, for example, when
17
+ # using Makara proxies for distributed Redis.
15
18
  cattr_accessor :redis_connector, default: ->(config) do
16
19
  ::Redis.new(config.except(:adapter, :channel_prefix))
17
20
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module SubscriptionAdapter
5
7
  class SubscriberMap
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  module SubscriptionAdapter
5
- # == \Test adapter for Action Cable
7
+ # ## Test adapter for Action Cable
6
8
  #
7
9
  # The test adapter should be used only in testing. Along with
8
- # ActionCable::TestHelper it makes a great tool to test your \Rails application.
10
+ # ActionCable::TestHelper it makes a great tool to test your Rails application.
9
11
  #
10
- # To use the test adapter set +adapter+ value to +test+ in your +config/cable.yml+ file.
12
+ # To use the test adapter set `adapter` value to `test` in your
13
+ # `config/cable.yml` file.
11
14
  #
12
- # NOTE: +Test+ adapter extends the +ActionCable::SubscriptionAdapter::Async+ adapter,
13
- # so it could be used in system tests too.
15
+ # NOTE: `Test` adapter extends the `ActionCable::SubscriptionAdapter::Async`
16
+ # adapter, so it could be used in system tests too.
14
17
  class Test < Async
15
18
  def broadcast(channel, payload)
16
19
  broadcasts(channel) << payload
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/test_case"
4
6
 
5
7
  module ActionCable
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionCable
4
6
  # Provides helper methods for testing Action Cable broadcasting
5
7
  module TestHelper
@@ -18,29 +20,30 @@ module ActionCable
18
20
  ActionCable.server.instance_variable_set(:@pubsub, @old_pubsub_adapter)
19
21
  end
20
22
 
21
- # Asserts that the number of broadcasted messages to the stream matches the given number.
22
- #
23
- # def test_broadcasts
24
- # assert_broadcasts 'messages', 0
25
- # ActionCable.server.broadcast 'messages', { text: 'hello' }
26
- # assert_broadcasts 'messages', 1
27
- # ActionCable.server.broadcast 'messages', { text: 'world' }
28
- # assert_broadcasts 'messages', 2
29
- # end
30
- #
31
- # If a block is passed, that block should cause the specified number of
32
- # messages to be broadcasted.
23
+ # Asserts that the number of broadcasted messages to the stream matches the
24
+ # given number.
33
25
  #
34
- # def test_broadcasts_again
35
- # assert_broadcasts('messages', 1) do
26
+ # def test_broadcasts
27
+ # assert_broadcasts 'messages', 0
36
28
  # ActionCable.server.broadcast 'messages', { text: 'hello' }
29
+ # assert_broadcasts 'messages', 1
30
+ # ActionCable.server.broadcast 'messages', { text: 'world' }
31
+ # assert_broadcasts 'messages', 2
37
32
  # end
38
33
  #
39
- # assert_broadcasts('messages', 2) do
40
- # ActionCable.server.broadcast 'messages', { text: 'hi' }
41
- # ActionCable.server.broadcast 'messages', { text: 'how are you?' }
34
+ # If a block is passed, that block should cause the specified number of messages
35
+ # to be broadcasted.
36
+ #
37
+ # def test_broadcasts_again
38
+ # assert_broadcasts('messages', 1) do
39
+ # ActionCable.server.broadcast 'messages', { text: 'hello' }
40
+ # end
41
+ #
42
+ # assert_broadcasts('messages', 2) do
43
+ # ActionCable.server.broadcast 'messages', { text: 'hi' }
44
+ # ActionCable.server.broadcast 'messages', { text: 'how are you?' }
45
+ # end
42
46
  # end
43
- # end
44
47
  #
45
48
  def assert_broadcasts(stream, number, &block)
46
49
  if block_given?
@@ -56,23 +59,23 @@ module ActionCable
56
59
 
57
60
  # Asserts that no messages have been sent to the stream.
58
61
  #
59
- # def test_no_broadcasts
60
- # assert_no_broadcasts 'messages'
61
- # ActionCable.server.broadcast 'messages', { text: 'hi' }
62
- # assert_broadcasts 'messages', 1
63
- # end
62
+ # def test_no_broadcasts
63
+ # assert_no_broadcasts 'messages'
64
+ # ActionCable.server.broadcast 'messages', { text: 'hi' }
65
+ # assert_broadcasts 'messages', 1
66
+ # end
64
67
  #
65
68
  # If a block is passed, that block should not cause any message to be sent.
66
69
  #
67
- # def test_broadcasts_again
68
- # assert_no_broadcasts 'messages' do
69
- # # No job messages should be sent from this block
70
+ # def test_broadcasts_again
71
+ # assert_no_broadcasts 'messages' do
72
+ # # No job messages should be sent from this block
73
+ # end
70
74
  # end
71
- # end
72
75
  #
73
76
  # Note: This assertion is simply a shortcut for:
74
77
  #
75
- # assert_broadcasts 'messages', 0, &block
78
+ # assert_broadcasts 'messages', 0, &block
76
79
  #
77
80
  def assert_no_broadcasts(stream, &block)
78
81
  assert_broadcasts stream, 0, &block
@@ -80,15 +83,15 @@ module ActionCable
80
83
 
81
84
  # Returns the messages that are broadcasted in the block.
82
85
  #
83
- # def test_broadcasts
84
- # messages = capture_broadcasts('messages') do
85
- # ActionCable.server.broadcast 'messages', { text: 'hi' }
86
- # ActionCable.server.broadcast 'messages', { text: 'how are you?' }
86
+ # def test_broadcasts
87
+ # messages = capture_broadcasts('messages') do
88
+ # ActionCable.server.broadcast 'messages', { text: 'hi' }
89
+ # ActionCable.server.broadcast 'messages', { text: 'how are you?' }
90
+ # end
91
+ # assert_equal 2, messages.length
92
+ # assert_equal({ text: 'hi' }, messages.first)
93
+ # assert_equal({ text: 'how are you?' }, messages.last)
87
94
  # end
88
- # assert_equal 2, messages.length
89
- # assert_equal({ text: 'hi' }, messages.first)
90
- # assert_equal({ text: 'how are you?' }, messages.last)
91
- # end
92
95
  #
93
96
  def capture_broadcasts(stream, &block)
94
97
  new_broadcasts_from(broadcasts(stream), stream, "capture_broadcasts", &block).map { |m| ActiveSupport::JSON.decode(m) }
@@ -96,23 +99,23 @@ module ActionCable
96
99
 
97
100
  # Asserts that the specified message has been sent to the stream.
98
101
  #
99
- # def test_assert_transmitted_message
100
- # ActionCable.server.broadcast 'messages', text: 'hello'
101
- # assert_broadcast_on('messages', text: 'hello')
102
- # end
102
+ # def test_assert_transmitted_message
103
+ # ActionCable.server.broadcast 'messages', text: 'hello'
104
+ # assert_broadcast_on('messages', text: 'hello')
105
+ # end
103
106
  #
104
- # If a block is passed, that block should cause a message with the specified data to be sent.
107
+ # If a block is passed, that block should cause a message with the specified
108
+ # data to be sent.
105
109
  #
106
- # def test_assert_broadcast_on_again
107
- # assert_broadcast_on('messages', text: 'hello') do
108
- # ActionCable.server.broadcast 'messages', text: 'hello'
110
+ # def test_assert_broadcast_on_again
111
+ # assert_broadcast_on('messages', text: 'hello') do
112
+ # ActionCable.server.broadcast 'messages', text: 'hello'
113
+ # end
109
114
  # end
110
- # end
111
115
  #
112
116
  def assert_broadcast_on(stream, data, &block)
113
- # Encode to JSON and back–we want to use this value to compare
114
- # with decoded JSON.
115
- # Comparing JSON strings doesn't work due to the order if the keys.
117
+ # Encode to JSON and back–we want to use this value to compare with decoded
118
+ # JSON. Comparing JSON strings doesn't work due to the order if the keys.
116
119
  serialized_msg =
117
120
  ActiveSupport::JSON.decode(ActiveSupport::JSON.encode(data))
118
121
 
@@ -1,9 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require_relative "gem_version"
4
6
 
5
7
  module ActionCable
6
- # Returns the currently loaded version of Action Cable as a +Gem::Version+.
8
+ # Returns the currently loaded version of Action Cable as a `Gem::Version`.
7
9
  def self.version
8
10
  gem_version
9
11
  end
data/lib/action_cable.rb CHANGED
@@ -31,6 +31,7 @@ Zeitwerk::Loader.for_gem.tap do |loader|
31
31
  loader.ignore(
32
32
  "#{__dir__}/rails", # Contains generators, templates, docs, etc.
33
33
  "#{__dir__}/action_cable/gem_version.rb",
34
+ "#{__dir__}/action_cable/version.rb",
34
35
  "#{__dir__}/action_cable/deprecator.rb",
35
36
  )
36
37
 
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module Rails
4
6
  module Generators
5
7
  class ChannelGenerator < NamedBase
@@ -103,8 +105,8 @@ pin_all_from "app/javascript/channels", under: "channels"
103
105
  end
104
106
 
105
107
  def using_bun?
106
- # Cannot assume bun.lockb has been generated yet so we look for
107
- # a file known to be generated by the jsbundling-rails gem
108
+ # Cannot assume bun.lockb has been generated yet so we look for a file known to
109
+ # be generated by the jsbundling-rails gem
108
110
  @using_bun ||= using_js_runtime? && root.join("bun.config.js").exist?
109
111
  end
110
112
 
@@ -1,3 +1,5 @@
1
+ # :markup: markdown
2
+
1
3
  module ApplicationCable
2
4
  class Channel < ActionCable::Channel::Base
3
5
  end
@@ -1,3 +1,5 @@
1
+ # :markup: markdown
2
+
1
3
  module ApplicationCable
2
4
  class Connection < ActionCable::Connection::Base
3
5
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module TestUnit
4
6
  module Generators
5
7
  class ChannelGenerator < ::Rails::Generators::NamedBase
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actioncable
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.1.5.2
4
+ version: 7.2.0.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pratik Naik
8
8
  - David Heinemeier Hansson
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 1980-01-02 00:00:00.000000000 Z
12
+ date: 2024-05-29 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: activesupport
@@ -16,28 +17,28 @@ dependencies:
16
17
  requirements:
17
18
  - - '='
18
19
  - !ruby/object:Gem::Version
19
- version: 7.1.5.2
20
+ version: 7.2.0.beta1
20
21
  type: :runtime
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - '='
25
26
  - !ruby/object:Gem::Version
26
- version: 7.1.5.2
27
+ version: 7.2.0.beta1
27
28
  - !ruby/object:Gem::Dependency
28
29
  name: actionpack
29
30
  requirement: !ruby/object:Gem::Requirement
30
31
  requirements:
31
32
  - - '='
32
33
  - !ruby/object:Gem::Version
33
- version: 7.1.5.2
34
+ version: 7.2.0.beta1
34
35
  type: :runtime
35
36
  prerelease: false
36
37
  version_requirements: !ruby/object:Gem::Requirement
37
38
  requirements:
38
39
  - - '='
39
40
  - !ruby/object:Gem::Version
40
- version: 7.1.5.2
41
+ version: 7.2.0.beta1
41
42
  - !ruby/object:Gem::Dependency
42
43
  name: nio4r
43
44
  requirement: !ruby/object:Gem::Requirement
@@ -153,11 +154,12 @@ licenses:
153
154
  - MIT
154
155
  metadata:
155
156
  bug_tracker_uri: https://github.com/rails/rails/issues
156
- changelog_uri: https://github.com/rails/rails/blob/v7.1.5.2/actioncable/CHANGELOG.md
157
- documentation_uri: https://api.rubyonrails.org/v7.1.5.2/
157
+ changelog_uri: https://github.com/rails/rails/blob/v7.2.0.beta1/actioncable/CHANGELOG.md
158
+ documentation_uri: https://api.rubyonrails.org/v7.2.0.beta1/
158
159
  mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
159
- source_code_uri: https://github.com/rails/rails/tree/v7.1.5.2/actioncable
160
+ source_code_uri: https://github.com/rails/rails/tree/v7.2.0.beta1/actioncable
160
161
  rubygems_mfa_required: 'true'
162
+ post_install_message:
161
163
  rdoc_options: []
162
164
  require_paths:
163
165
  - lib
@@ -165,14 +167,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
167
  requirements:
166
168
  - - ">="
167
169
  - !ruby/object:Gem::Version
168
- version: 2.7.0
170
+ version: 3.1.0
169
171
  required_rubygems_version: !ruby/object:Gem::Requirement
170
172
  requirements:
171
173
  - - ">="
172
174
  - !ruby/object:Gem::Version
173
175
  version: '0'
174
176
  requirements: []
175
- rubygems_version: 3.6.9
177
+ rubygems_version: 3.5.10
178
+ signing_key:
176
179
  specification_version: 4
177
180
  summary: WebSocket framework for Rails.
178
181
  test_files: []