aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/lib/action_cable
diff options
context:
space:
mode:
Diffstat (limited to 'actioncable/lib/action_cable')
-rw-r--r--actioncable/lib/action_cable/channel/base.rb4
-rw-r--r--actioncable/lib/action_cable/channel/test_case.rb49
-rw-r--r--actioncable/lib/action_cable/connection/authorization.rb2
-rw-r--r--actioncable/lib/action_cable/connection/base.rb11
-rw-r--r--actioncable/lib/action_cable/server/base.rb4
-rw-r--r--actioncable/lib/action_cable/server/worker.rb12
6 files changed, 66 insertions, 16 deletions
diff --git a/actioncable/lib/action_cable/channel/base.rb b/actioncable/lib/action_cable/channel/base.rb
index 70c93ec0f3..ad0d3685cd 100644
--- a/actioncable/lib/action_cable/channel/base.rb
+++ b/actioncable/lib/action_cable/channel/base.rb
@@ -1,6 +1,7 @@
# frozen_string_literal: true
require "set"
+require "active_support/rescuable"
module ActionCable
module Channel
@@ -99,6 +100,7 @@ module ActionCable
include Streams
include Naming
include Broadcasting
+ include ActiveSupport::Rescuable
attr_reader :params, :connection, :identifier
delegate :logger, to: :connection
@@ -267,6 +269,8 @@ module ActionCable
else
public_send action
end
+ rescue Exception => exception
+ rescue_with_handler(exception) || raise
end
def action_signature(action, data)
diff --git a/actioncable/lib/action_cable/channel/test_case.rb b/actioncable/lib/action_cable/channel/test_case.rb
index dd2762ccd0..c4cf0ac0e7 100644
--- a/actioncable/lib/action_cable/channel/test_case.rb
+++ b/actioncable/lib/action_cable/channel/test_case.rb
@@ -84,7 +84,18 @@ module ActionCable
# assert subscription.confirmed?
#
# # Asserts that the channel subscribes connection to a stream
- # assert_equal "chat_1", streams.last
+ # assert_has_stream "chat_1"
+ #
+ # # Asserts that the channel subscribes connection to a specific
+ # # stream created for a model
+ # assert_has_stream_for Room.find(1)
+ # end
+ #
+ # def test_does_not_stream_with_incorrect_room_number
+ # subscribe room_number: -1
+ #
+ # # Asserts that not streams was started
+ # assert_no_streams
# end
#
# def test_does_not_subscribe_without_room_number
@@ -115,8 +126,6 @@ module ActionCable
# An instance of the current channel, created when you call `subscribe`.
# <b>transmissions</b>::
# A list of all messages that have been transmitted into the channel.
- # <b>streams</b>::
- # A list of all created streams subscriptions (as identifiers) for the subscription.
#
#
# == Channel is automatically inferred
@@ -167,7 +176,6 @@ module ActionCable
class_attribute :_channel_class
attr_reader :connection, :subscription
- delegate :streams, to: :subscription
ActiveSupport.run_load_hooks(:action_cable_channel_test_case, self)
end
@@ -251,6 +259,39 @@ module ActionCable
super(broadcasting_for(stream_or_object), *args)
end
+ # Asserts that no streams have been started.
+ #
+ # def test_assert_no_started_stream
+ # subscribe
+ # assert_no_streams
+ # end
+ #
+ def assert_no_streams
+ assert subscription.streams.empty?, "No streams started was expected, but #{subscription.streams.count} found"
+ end
+
+ # Asserts that the specified stream has been started.
+ #
+ # def test_assert_started_stream
+ # subscribe
+ # assert_has_stream 'messages'
+ # end
+ #
+ def assert_has_stream(stream)
+ assert subscription.streams.include?(stream), "Stream #{stream} has not been started"
+ end
+
+ # Asserts that the specified stream for a model has started.
+ #
+ # def test_assert_started_stream_for
+ # subscribe id: 42
+ # assert_has_stream_for User.find(42)
+ # end
+ #
+ def assert_has_stream_for(object)
+ assert_has_stream(broadcasting_for(object))
+ end
+
private
def check_subscribed!
raise "Must be subscribed!" if subscription.nil? || subscription.rejected?
diff --git a/actioncable/lib/action_cable/connection/authorization.rb b/actioncable/lib/action_cable/connection/authorization.rb
index a22179d988..aef3386f71 100644
--- a/actioncable/lib/action_cable/connection/authorization.rb
+++ b/actioncable/lib/action_cable/connection/authorization.rb
@@ -5,7 +5,7 @@ module ActionCable
module Authorization
class UnauthorizedError < StandardError; end
- # Closes the \WebSocket connection if it is open and returns a 404 "File not Found" response.
+ # Closes the WebSocket connection if it is open and returns a 404 "File not Found" response.
def reject_unauthorized_connection
logger.error "An unauthorized connection attempt was rejected"
raise UnauthorizedError
diff --git a/actioncable/lib/action_cable/connection/base.rb b/actioncable/lib/action_cable/connection/base.rb
index 11a1f1a5e8..0044afad98 100644
--- a/actioncable/lib/action_cable/connection/base.rb
+++ b/actioncable/lib/action_cable/connection/base.rb
@@ -95,7 +95,12 @@ module ActionCable
end
# Close the WebSocket connection.
- def close
+ def close(reason: nil, reconnect: true)
+ transmit(
+ type: ActionCable::INTERNAL[:message_types][:disconnect],
+ reason: reason,
+ reconnect: reconnect
+ )
websocket.close
end
@@ -170,7 +175,7 @@ module ActionCable
message_buffer.process!
server.add_connection(self)
rescue ActionCable::Connection::Authorization::UnauthorizedError
- respond_to_invalid_request
+ close(reason: ActionCable::INTERNAL[:disconnect_reasons][:unauthorized], reconnect: false) if websocket.alive?
end
def handle_close
@@ -211,7 +216,7 @@ module ActionCable
end
def respond_to_invalid_request
- close if websocket.alive?
+ close(reason: ActionCable::INTERNAL[:disconnect_reasons][:invalid_request]) if websocket.alive?
logger.error invalid_request_message
logger.info finished_request_message
diff --git a/actioncable/lib/action_cable/server/base.rb b/actioncable/lib/action_cable/server/base.rb
index 1ee03f6dfc..2b9e1cba3b 100644
--- a/actioncable/lib/action_cable/server/base.rb
+++ b/actioncable/lib/action_cable/server/base.rb
@@ -36,7 +36,9 @@ module ActionCable
end
def restart
- connections.each(&:close)
+ connections.each do |connection|
+ connection.close(reason: ActionCable::INTERNAL[:disconnect_reasons][:server_restart])
+ end
@mutex.synchronize do
# Shutdown the worker pool
diff --git a/actioncable/lib/action_cable/server/worker.rb b/actioncable/lib/action_cable/server/worker.rb
index c69cc4ac31..187c8f7939 100644
--- a/actioncable/lib/action_cable/server/worker.rb
+++ b/actioncable/lib/action_cable/server/worker.rb
@@ -56,14 +56,12 @@ module ActionCable
def invoke(receiver, method, *args, connection:, &block)
work(connection) do
- begin
- receiver.send method, *args, &block
- rescue Exception => e
- logger.error "There was an exception - #{e.class}(#{e.message})"
- logger.error e.backtrace.join("\n")
+ receiver.send method, *args, &block
+ rescue Exception => e
+ logger.error "There was an exception - #{e.class}(#{e.message})"
+ logger.error e.backtrace.join("\n")
- receiver.handle_exception if receiver.respond_to?(:handle_exception)
- end
+ receiver.handle_exception if receiver.respond_to?(:handle_exception)
end
end