diff options
Diffstat (limited to 'actioncable/lib/action_cable')
-rw-r--r-- | actioncable/lib/action_cable/channel/periodic_timers.rb | 4 | ||||
-rw-r--r-- | actioncable/lib/action_cable/channel/streams.rb | 2 | ||||
-rw-r--r-- | actioncable/lib/action_cable/connection/stream.rb | 1 | ||||
-rw-r--r-- | actioncable/lib/action_cable/connection/subscriptions.rb | 6 | ||||
-rw-r--r-- | actioncable/lib/action_cable/engine.rb | 9 | ||||
-rw-r--r-- | actioncable/lib/action_cable/server/base.rb | 16 | ||||
-rw-r--r-- | actioncable/lib/action_cable/server/configuration.rb | 10 | ||||
-rw-r--r-- | actioncable/lib/action_cable/server/worker.rb | 12 |
8 files changed, 21 insertions, 39 deletions
diff --git a/actioncable/lib/action_cable/channel/periodic_timers.rb b/actioncable/lib/action_cable/channel/periodic_timers.rb index dab604440f..41511312fc 100644 --- a/actioncable/lib/action_cable/channel/periodic_timers.rb +++ b/actioncable/lib/action_cable/channel/periodic_timers.rb @@ -64,9 +64,7 @@ module ActionCable def start_periodic_timer(callback, every:) connection.server.event_loop.timer every do - connection.worker_pool.async_invoke connection do - instance_exec(&callback) - end + connection.worker_pool.async_exec self, connection: connection, &callback end end diff --git a/actioncable/lib/action_cable/channel/streams.rb b/actioncable/lib/action_cable/channel/streams.rb index 0a0a95f453..561750d713 100644 --- a/actioncable/lib/action_cable/channel/streams.rb +++ b/actioncable/lib/action_cable/channel/streams.rb @@ -138,7 +138,7 @@ module ActionCable end # May be overridden to change the default stream handling behavior - # which decodes JSON and transmits to client. + # which decodes JSON and transmits to the client. # # TODO: Tests demonstrating this. # diff --git a/actioncable/lib/action_cable/connection/stream.rb b/actioncable/lib/action_cable/connection/stream.rb index 0cf59091bc..c250cf92fc 100644 --- a/actioncable/lib/action_cable/connection/stream.rb +++ b/actioncable/lib/action_cable/connection/stream.rb @@ -50,6 +50,7 @@ module ActionCable def clean_rack_hijack return unless @rack_hijack_io @event_loop.detach(@rack_hijack_io, self) + @rack_hijack_io.close @rack_hijack_io = nil end end 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..34f9952c71 100644 --- a/actioncable/lib/action_cable/engine.rb +++ b/actioncable/lib/action_cable/engine.rb @@ -22,7 +22,7 @@ module ActionCable initializer "action_cable.set_configs" do |app| options = app.config.action_cable - options.allowed_request_origins ||= "http://localhost:3000" if ::Rails.env.development? + options.allowed_request_origins ||= /https?:\/\/localhost:\d+/ if ::Rails.env.development? app.paths.add "config/cable", with: "config/cable.yml" @@ -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. diff --git a/actioncable/lib/action_cable/server/worker.rb b/actioncable/lib/action_cable/server/worker.rb index a638ff72e7..f3a4fc5a5b 100644 --- a/actioncable/lib/action_cable/server/worker.rb +++ b/actioncable/lib/action_cable/server/worker.rb @@ -42,16 +42,20 @@ module ActionCable self.connection = nil end - def async_invoke(receiver, method, *args, connection: receiver) + def async_exec(receiver, *args, connection:, &block) + async_invoke receiver, :instance_exec, *args, connection: connection, &block + end + + def async_invoke(receiver, method, *args, connection: receiver, &block) @executor.post do - invoke(receiver, method, *args, connection: connection) + invoke(receiver, method, *args, connection: connection, &block) end end - def invoke(receiver, method, *args, connection:) + def invoke(receiver, method, *args, connection:, &block) work(connection) do begin - receiver.send method, *args + receiver.send method, *args, &block rescue Exception => e logger.error "There was an exception - #{e.class}(#{e.message})" logger.error e.backtrace.join("\n") |