Skip to content

Commit 98fa489

Browse files
committed
* sync with upstream
Ref c594ba4ffdb016c7b2a22055f41dfb2c4409594d
1 parent c0bd5d6 commit 98fa489

29 files changed

Lines changed: 347 additions & 151 deletions

.github/workflows/benchmark.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
- uses: actions/checkout@v4
3737
- uses: ruby/setup-ruby@v1
3838
with:
39-
ruby-version: 3.3
39+
ruby-version: 3.4
4040
bundler-cache: true
4141
- name: Run benchmarks
4242
env:

.github/workflows/lint.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
- uses: actions/checkout@v4
2626
- uses: ruby/setup-ruby@v1
2727
with:
28-
ruby-version: 3.3
28+
ruby-version: 3.4
2929
bundler-cache: true
3030
- name: Lint Ruby code with RuboCop
3131
run: |

.rubocop.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require:
1+
plugins:
22
- rubocop-minitest
33
- rubocop-packaging
44
- rubocop-performance
@@ -215,6 +215,9 @@ Layout/TrailingWhitespace:
215215
Style/RedundantPercentQ:
216216
Enabled: true
217217

218+
Lint/NestedMethodDefinition:
219+
Enabled: true
220+
218221
Lint/AmbiguousOperator:
219222
Enabled: true
220223

@@ -328,6 +331,9 @@ Style/OpenStructUse:
328331
Style/ArrayIntersect:
329332
Enabled: true
330333

334+
Style/KeywordArgumentsMerging:
335+
Enabled: true
336+
331337
Performance/BindCall:
332338
Enabled: true
333339

@@ -376,7 +382,7 @@ Performance/RedundantStringChars:
376382
Performance/StringInclude:
377383
Enabled: true
378384

379-
Minitest/AssertPredicate:
385+
Minitest/AssertNil:
380386
Enabled: true
381387

382388
Minitest/AssertRaisesWithRegexpArgument:

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## main
44

5+
- Sync with upstream (Rails 8.1.1).
6+
57
- Do not call `#subscribed` when subscription is rejected in a `before_subscribe` callback.
68

79
## 0.2.0

Rakefile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,28 @@ require "action_cable"
88

99
task default: :test
1010

11-
task :package
12-
1311
ENV["RAILS_MINITEST_PLUGIN"] = "true"
1412

1513
Rake::TestTask.new do |t|
1614
t.libs << "test"
1715
t.test_files = FileList["#{__dir__}/test/**/*_test.rb"]
1816
t.warning = true
1917
t.verbose = true
18+
t.options = "--profile" if ENV["CI"]
2019
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
2120
end
2221

2322
namespace :test do
24-
task :isolated do
23+
task isolated: :railties do
2524
Dir.glob("test/**/*_test.rb").all? do |file|
2625
sh(Gem.ruby, "-w", "-Ilib:test", file)
2726
end || raise("Failures")
2827
end
28+
29+
task :railties do
30+
# TODO: uncomment in rails/rails
31+
# ["action_cable/engine"].all? do |railtie|
32+
# sh(Gem.ruby, "-r", railtie, "-e", "'OK'")
33+
# end || raise("Failures")
34+
end
2935
end

actioncable-next.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
99
s.summary = "Next-gen version of Action Cable"
1010
s.description = "Next-gen version of Action Cable"
1111

12-
s.required_ruby_version = ">= 3.1.0"
12+
s.required_ruby_version = ">= 3.2.0"
1313

1414
s.license = "MIT"
1515

lib/action_cable/channel/base.rb

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
# :markup: markdown
44

5-
require "set"
65
require "active_support/rescuable"
76
require "active_support/parameter_filter"
87

@@ -133,7 +132,10 @@ def action_methods
133132
# Except for public instance methods of Base and its ancestors
134133
ActionCable::Channel::Base.public_instance_methods(true) +
135134
# Be sure to include shadowed public instance methods of this class
136-
public_instance_methods(false)).uniq.map(&:to_s)
135+
public_instance_methods(false) -
136+
# Except the internal methods
137+
internal_methods).uniq
138+
methods.map!(&:name)
137139
methods.to_set
138140
end
139141
end
@@ -146,6 +148,10 @@ def clear_action_methods! # :doc:
146148
@action_methods = nil
147149
end
148150

151+
def internal_methods
152+
super
153+
end
154+
149155
# Refresh the cached action_methods when a new action_method is added.
150156
def method_added(name) # :doc:
151157
super
@@ -166,6 +172,7 @@ def initialize(connection, identifier, params = {})
166172

167173
@reject_subscription = nil
168174
@subscription_confirmation_sent = nil
175+
@unsubscribed = false
169176

170177
delegate_connection_identifiers
171178
end
@@ -201,11 +208,16 @@ def subscribe_to_channel
201208
# cleanup with callbacks. This method is not intended to be called directly by
202209
# the user. Instead, override the #unsubscribed callback.
203210
def unsubscribe_from_channel # :nodoc:
211+
@unsubscribed = true
204212
run_callbacks :unsubscribe do
205213
unsubscribed
206214
end
207215
end
208216

217+
def unsubscribed? # :nodoc:
218+
@unsubscribed
219+
end
220+
209221
private
210222
# Called once a consumer has become a subscriber of the channel. Usually the
211223
# place to set up any streams you want this channel to be sending to the

lib/action_cable/channel/broadcasting.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ module Broadcasting
1010
extend ActiveSupport::Concern
1111

1212
module ClassMethods
13-
# Broadcast a hash to a unique broadcasting for this `model` in this channel.
14-
def broadcast_to(model, message)
15-
ActionCable.server.broadcast(broadcasting_for(model), message)
13+
# Broadcast a hash to a unique broadcasting for this array of `broadcastables` in this channel.
14+
def broadcast_to(broadcastables, message)
15+
ActionCable.server.broadcast(broadcasting_for(broadcastables), message)
1616
end
1717

1818
# Returns a unique broadcasting identifier for this `model` in this channel:
1919
#
2020
# CommentsChannel.broadcasting_for("all") # => "comments:all"
2121
#
22-
# You can pass any object as a target (e.g. Active Record model), and it would
22+
# You can pass an array of objects as a target (e.g. Active Record model), and it would
2323
# be serialized into a string under the hood.
24-
def broadcasting_for(model)
25-
serialize_broadcasting([ channel_name, model ])
24+
def broadcasting_for(broadcastables)
25+
serialize_broadcasting([ channel_name ] + Array(broadcastables))
2626
end
2727

2828
private

lib/action_cable/channel/callbacks.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ module Callbacks
3939
extend ActiveSupport::Concern
4040
include ActiveSupport::Callbacks
4141

42+
INTERNAL_METHODS = [:_run_subscribe_callbacks, :_run_unsubscribe_callbacks] # :nodoc:
43+
4244
included do
4345
define_callbacks :subscribe
4446
define_callbacks :unsubscribe
@@ -70,6 +72,11 @@ def after_unsubscribe(*methods, &block)
7072
set_callback(:unsubscribe, :after, *methods, &block)
7173
end
7274
alias_method :on_unsubscribe, :after_unsubscribe
75+
76+
private
77+
def internal_methods
78+
INTERNAL_METHODS
79+
end
7380
end
7481
end
7582
end

lib/action_cable/channel/streams.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ module Streams
8888
# callback. Defaults to `coder: nil` which does no decoding, passes raw
8989
# messages.
9090
def stream_from(broadcasting, callback = nil, coder: nil, &block)
91+
return if unsubscribed?
92+
9193
broadcasting = String(broadcasting)
9294

9395
# Don't send the confirmation until pubsub#subscribe is successful
@@ -104,15 +106,15 @@ def stream_from(broadcasting, callback = nil, coder: nil, &block)
104106
end)
105107
end
106108

107-
# Start streaming the pubsub queue for the `model` in this channel. Optionally,
109+
# Start streaming the pubsub queue for the `broadcastables` in this channel. Optionally,
108110
# you can pass a `callback` that'll be used instead of the default of just
109111
# transmitting the updates straight to the subscriber.
110112
#
111113
# Pass `coder: ActiveSupport::JSON` to decode messages as JSON before passing to
112114
# the callback. Defaults to `coder: nil` which does no decoding, passes raw
113115
# messages.
114-
def stream_for(model, ...)
115-
stream_from(broadcasting_for(model), ...)
116+
def stream_for(broadcastables, ...)
117+
stream_from(broadcasting_for(broadcastables), ...)
116118
end
117119

118120
# Unsubscribes streams from the named `broadcasting`.

0 commit comments

Comments
 (0)