Skip to content

Commit fe97e03

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

26 files changed

Lines changed: 242 additions & 147 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: |

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+
# TODO: Uncomment in rails/rails
19+
# t.options = "--profile" if ENV["CI"]
2020
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
2121
end
2222

2323
namespace :test do
24-
task :isolated do
24+
task isolated: :railties do
2525
Dir.glob("test/**/*_test.rb").all? do |file|
2626
sh(Gem.ruby, "-w", "-Ilib:test", file)
2727
end || raise("Failures")
2828
end
29+
30+
task :railties do
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`.

lib/action_cable/connection/test_case.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,11 +142,8 @@ def unsubscribe(stream, callback)
142142
#
143143
# ## Basic example
144144
#
145-
# Unit tests are written as follows:
146-
#
147-
# 1. Simulate a connection attempt by calling `connect`.
148-
# 2. Assert state, e.g. identifiers, has been assigned.
149-
#
145+
# Unit tests are written by first simulating a connection attempt by calling
146+
# `connect` and then asserting state, e.g. identifiers, have been assigned.
150147
#
151148
# class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase
152149
# def test_connects_with_proper_cookie

0 commit comments

Comments
 (0)