From a8df1bc345bf062e98bda64ef9638f65292c4b56 Mon Sep 17 00:00:00 2001 From: Matthew Draper Date: Thu, 2 Jun 2016 04:08:48 +0930 Subject: Properly support reloading for Action Cable channels --- actioncable/lib/action_cable/connection/subscriptions.rb | 6 +++--- actioncable/lib/action_cable/engine.rb | 7 ++----- actioncable/lib/action_cable/server/base.rb | 16 +++------------- actioncable/lib/action_cable/server/configuration.rb | 10 +--------- 4 files changed, 9 insertions(+), 30 deletions(-) (limited to 'actioncable/lib') diff --git a/actioncable/lib/action_cable/connection/subscriptions.rb b/actioncable/lib/action_cable/connection/subscriptions.rb index 3742f248d1..6051818bfb 100644 --- a/actioncable/lib/action_cable/connection/subscriptions.rb +++ b/actioncable/lib/action_cable/connection/subscriptions.rb @@ -26,12 +26,12 @@ module ActionCable id_key = data['identifier'] id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access - subscription_klass = connection.server.channel_classes[id_options[:channel]] + subscription_klass = id_options[:channel].safe_constantize - if subscription_klass + if subscription_klass && ActionCable::Channel::Base >= subscription_klass subscriptions[id_key] ||= subscription_klass.new(connection, id_key, id_options) else - logger.error "Subscription class not found (#{data.inspect})" + logger.error "Subscription class not found: #{id_options[:channel].inspect}" end end diff --git a/actioncable/lib/action_cable/engine.rb b/actioncable/lib/action_cable/engine.rb index 8ce1b24962..96176e0014 100644 --- a/actioncable/lib/action_cable/engine.rb +++ b/actioncable/lib/action_cable/engine.rb @@ -31,11 +31,8 @@ module ActionCable self.cable = Rails.application.config_for(config_path).with_indifferent_access end - if 'ApplicationCable::Connection'.safe_constantize - self.connection_class = ApplicationCable::Connection - end - - self.channel_paths = Rails.application.paths['app/channels'].existent + previous_connection_class = self.connection_class + self.connection_class = -> { 'ApplicationCable::Connection'.safe_constantize || previous_connection_class.call } options.each { |k,v| send("#{k}=", v) } end diff --git a/actioncable/lib/action_cable/server/base.rb b/actioncable/lib/action_cable/server/base.rb index 717a60fe4f..0ad1e408a9 100644 --- a/actioncable/lib/action_cable/server/base.rb +++ b/actioncable/lib/action_cable/server/base.rb @@ -19,13 +19,13 @@ module ActionCable def initialize @mutex = Monitor.new - @remote_connections = @event_loop = @worker_pool = @channel_classes = @pubsub = nil + @remote_connections = @event_loop = @worker_pool = @pubsub = nil end # Called by Rack to setup the server. def call(env) setup_heartbeat_timer - config.connection_class.new(self, env).process + config.connection_class.call.new(self, env).process end # Disconnect all the connections identified by `identifiers` on this server or any others via RemoteConnections. @@ -67,16 +67,6 @@ module ActionCable @worker_pool || @mutex.synchronize { @worker_pool ||= ActionCable::Server::Worker.new(max_size: config.worker_pool_size) } end - # Requires and returns a hash of all of the channel class constants, which are keyed by name. - def channel_classes - @channel_classes || @mutex.synchronize do - @channel_classes ||= begin - config.channel_paths.each { |channel_path| require channel_path } - config.channel_class_names.each_with_object({}) { |name, hash| hash[name] = name.constantize } - end - end - end - # Adapter used for all streams/broadcasting. def pubsub @pubsub || @mutex.synchronize { @pubsub ||= config.pubsub_adapter.new(self) } @@ -84,7 +74,7 @@ module ActionCable # All of the identifiers applied to the connection class associated with this server. def connection_identifiers - config.connection_class.identifiers + config.connection_class.call.identifiers end end diff --git a/actioncable/lib/action_cable/server/configuration.rb b/actioncable/lib/action_cable/server/configuration.rb index 0bb378cf03..ada1ac22cc 100644 --- a/actioncable/lib/action_cable/server/configuration.rb +++ b/actioncable/lib/action_cable/server/configuration.rb @@ -8,23 +8,15 @@ module ActionCable attr_accessor :disable_request_forgery_protection, :allowed_request_origins attr_accessor :cable, :url, :mount_path - attr_accessor :channel_paths # :nodoc: - def initialize @log_tags = [] - @connection_class = ActionCable::Connection::Base + @connection_class = -> { ActionCable::Connection::Base } @worker_pool_size = 4 @disable_request_forgery_protection = false end - def channel_class_names - @channel_class_names ||= channel_paths.collect do |channel_path| - Pathname.new(channel_path).basename.to_s.split('.').first.camelize - end - end - # Returns constant of subscription adapter specified in config/cable.yml. # If the adapter cannot be found, this will default to the Redis adapter. # Also makes sure proper dependencies are required. -- cgit v1.2.3