mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Extract Server configuration into a Configuration object
This commit is contained in:
parent
44e7cc324d
commit
b8b50e6b04
7 changed files with 82 additions and 35 deletions
|
@ -117,7 +117,7 @@ module ActionCable
|
|||
# Tags are declared in the server but computed in the connection. This allows us per-connection tailored tags.
|
||||
def new_tagged_logger
|
||||
TaggedLoggerProxy.new server.logger,
|
||||
tags: server.log_tags.map { |tag| tag.respond_to?(:call) ? tag.call(request) : tag.to_s.camelize }
|
||||
tags: server.config.log_tags.map { |tag| tag.respond_to?(:call) ? tag.call(request) : tag.to_s.camelize }
|
||||
end
|
||||
|
||||
def started_request_message
|
||||
|
|
|
@ -22,8 +22,8 @@ module ActionCable
|
|||
id_key = data['identifier']
|
||||
id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access
|
||||
|
||||
subscription_klass = connection.server.registered_channels.detect do |channel_klass|
|
||||
channel_klass == id_options[:channel].safe_constantize
|
||||
subscription_klass = connection.server.channel_classes.detect do |channel_class|
|
||||
channel_class == id_options[:channel].safe_constantize
|
||||
end
|
||||
|
||||
if subscription_klass
|
||||
|
|
|
@ -3,6 +3,7 @@ module ActionCable
|
|||
autoload :Base, 'action_cable/server/base'
|
||||
autoload :Broadcasting, 'action_cable/server/broadcasting'
|
||||
autoload :Connections, 'action_cable/server/connections'
|
||||
autoload :Configuration, 'action_cable/server/configuration'
|
||||
autoload :Worker, 'action_cable/server/worker'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,43 +4,26 @@ module ActionCable
|
|||
include ActionCable::Server::Broadcasting
|
||||
include ActionCable::Server::Connections
|
||||
|
||||
cattr_accessor(:logger, instance_reader: true) { Rails.logger }
|
||||
cattr_accessor(:config, instance_accessor: true) { ActionCable::Server::Configuration.new }
|
||||
|
||||
attr_accessor :registered_channels, :redis_config, :log_tags
|
||||
def self.logger; config.logger; end
|
||||
delegate :logger, to: :config
|
||||
|
||||
def initialize(redis_config:, channels:, worker_pool_size: 100, connection: Connection, log_tags: [ 'ActionCable' ])
|
||||
@redis_config = redis_config.with_indifferent_access
|
||||
@registered_channels = Set.new(channels)
|
||||
@worker_pool_size = worker_pool_size
|
||||
@connection_class = connection
|
||||
@log_tags = log_tags
|
||||
|
||||
@connections = []
|
||||
|
||||
logger.info "[ActionCable] Initialized server (redis_config: #{@redis_config.inspect}, worker_pool_size: #{@worker_pool_size})"
|
||||
def initialize
|
||||
end
|
||||
|
||||
def call(env)
|
||||
@connection_class.new(self, env).process
|
||||
config.connection_class.new(self, env).process
|
||||
end
|
||||
|
||||
def worker_pool
|
||||
@worker_pool ||= ActionCable::Server::Worker.pool(size: @worker_pool_size)
|
||||
@worker_pool ||= ActionCable::Server::Worker.pool(size: config.worker_pool_size)
|
||||
end
|
||||
|
||||
def pubsub
|
||||
@pubsub ||= redis.pubsub
|
||||
end
|
||||
|
||||
def redis
|
||||
@redis ||= begin
|
||||
redis = EM::Hiredis.connect(@redis_config[:url])
|
||||
redis.on(:reconnect_failed) do
|
||||
logger.info "[ActionCable] Redis reconnect failed."
|
||||
# logger.info "[ActionCable] Redis reconnected. Closing all the open connections."
|
||||
# @connections.map &:close
|
||||
end
|
||||
redis
|
||||
def channel_classes
|
||||
@channel_classes ||= begin
|
||||
config.channel_paths.each { |channel_path| require channel_path }
|
||||
config.channel_class_names.collect { |name| name.constantize }
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -48,10 +31,22 @@ module ActionCable
|
|||
@remote_connections ||= RemoteConnections.new(self)
|
||||
end
|
||||
|
||||
def connection_identifiers
|
||||
@connection_class.identifiers
|
||||
def pubsub
|
||||
@pubsub ||= redis.pubsub
|
||||
end
|
||||
|
||||
def redis
|
||||
@redis ||= EM::Hiredis.connect(config.redis[:url]).tap do |redis|
|
||||
redis.on(:reconnect_failed) do
|
||||
logger.info "[ActionCable] Redis reconnect failed."
|
||||
# logger.info "[ActionCable] Redis reconnected. Closing all the open connections."
|
||||
# @connections.map &:close
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def connection_identifiers
|
||||
config.connection_class.identifiers
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,7 @@ module ActionCable
|
|||
end
|
||||
|
||||
def broadcasting_redis
|
||||
@broadcasting_redis ||= Redis.new(redis_config)
|
||||
@broadcasting_redis ||= Redis.new(config.redis)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
51
lib/action_cable/server/configuration.rb
Normal file
51
lib/action_cable/server/configuration.rb
Normal file
|
@ -0,0 +1,51 @@
|
|||
module ActionCable
|
||||
module Server
|
||||
class Configuration
|
||||
attr_accessor :logger, :log_tags
|
||||
attr_accessor :connection_class, :worker_pool_size
|
||||
attr_accessor :redis_path, :channels_path
|
||||
|
||||
def initialize
|
||||
@logger = Rails.logger
|
||||
@log_tags = []
|
||||
|
||||
@connection_class = ApplicationCable::Connection
|
||||
@worker_pool_size = 100
|
||||
|
||||
@redis_path = Rails.root.join('config/redis/cable.yml')
|
||||
@channels_path = Rails.root.join('app/channels')
|
||||
end
|
||||
|
||||
def channel_paths
|
||||
@channels ||= Dir["#{channels_path}/**/*_channel.rb"]
|
||||
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
|
||||
|
||||
def redis
|
||||
@redis ||= config_for(redis_path).with_indifferent_access
|
||||
end
|
||||
|
||||
private
|
||||
# FIXME: Extract this from Rails::Application in a way it can be used here.
|
||||
def config_for(path)
|
||||
if path.exist?
|
||||
require "yaml"
|
||||
require "erb"
|
||||
(YAML.load(ERB.new(path.read).result) || {})[Rails.env] || {}
|
||||
else
|
||||
raise "Could not load configuration. No such file - #{path}"
|
||||
end
|
||||
rescue Psych::SyntaxError => e
|
||||
raise "YAML syntax error occurred while parsing #{path}. " \
|
||||
"Please note that YAML must be consistently indented using spaces. Tabs are not allowed. " \
|
||||
"Error: #{e.message}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -17,7 +17,7 @@ class ServerTest < ActionCableTest
|
|||
end
|
||||
|
||||
test "channel registration" do
|
||||
assert_equal ChatServer.registered_channels, Set.new([ ChatChannel ])
|
||||
assert_equal ChatServer.channel_classes, Set.new([ ChatChannel ])
|
||||
end
|
||||
|
||||
test "subscribing to a channel with valid params" do
|
||||
|
|
Loading…
Reference in a new issue