diff options
Diffstat (limited to 'actioncable/lib/action_cable/subscription_adapter')
8 files changed, 29 insertions, 95 deletions
diff --git a/actioncable/lib/action_cable/subscription_adapter/async.rb b/actioncable/lib/action_cable/subscription_adapter/async.rb index 46819dbfec..c9930299c7 100644 --- a/actioncable/lib/action_cable/subscription_adapter/async.rb +++ b/actioncable/lib/action_cable/subscription_adapter/async.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "action_cable/subscription_adapter/inline" module ActionCable diff --git a/actioncable/lib/action_cable/subscription_adapter/base.rb b/actioncable/lib/action_cable/subscription_adapter/base.rb index 796db5ffa3..34077707fd 100644 --- a/actioncable/lib/action_cable/subscription_adapter/base.rb +++ b/actioncable/lib/action_cable/subscription_adapter/base.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActionCable module SubscriptionAdapter class Base diff --git a/actioncable/lib/action_cable/subscription_adapter/channel_prefix.rb b/actioncable/lib/action_cable/subscription_adapter/channel_prefix.rb index 8b293cc785..df0aa040f5 100644 --- a/actioncable/lib/action_cable/subscription_adapter/channel_prefix.rb +++ b/actioncable/lib/action_cable/subscription_adapter/channel_prefix.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActionCable module SubscriptionAdapter module ChannelPrefix # :nodoc: diff --git a/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb b/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb deleted file mode 100644 index ed8f315791..0000000000 --- a/actioncable/lib/action_cable/subscription_adapter/evented_redis.rb +++ /dev/null @@ -1,87 +0,0 @@ -require "thread" - -gem "em-hiredis", "~> 0.3.0" -gem "redis", "~> 3.0" -require "em-hiredis" -require "redis" - -EventMachine.epoll if EventMachine.epoll? -EventMachine.kqueue if EventMachine.kqueue? - -module ActionCable - module SubscriptionAdapter - class EventedRedis < Base # :nodoc: - prepend ChannelPrefix - - @@mutex = Mutex.new - - # Overwrite this factory method for EventMachine Redis connections if you want to use a different Redis connection library than EM::Hiredis. - # This is needed, for example, when using Makara proxies for distributed Redis. - cattr_accessor(:em_redis_connector) { ->(config) { EM::Hiredis.connect(config[:url]) } } - - # Overwrite this factory method for Redis connections if you want to use a different Redis connection library than Redis. - # This is needed, for example, when using Makara proxies for distributed Redis. - cattr_accessor(:redis_connector) { ->(config) { ::Redis.new(url: config[:url]) } } - - def initialize(*) - ActiveSupport::Deprecation.warn(<<-MSG.squish) - The "evented_redis" subscription adapter is deprecated and - will be removed in Rails 5.2. Please use the "redis" adapter - instead. - MSG - - super - @redis_connection_for_broadcasts = @redis_connection_for_subscriptions = nil - end - - def broadcast(channel, payload) - redis_connection_for_broadcasts.publish(channel, payload) - end - - def subscribe(channel, message_callback, success_callback = nil) - redis_connection_for_subscriptions.pubsub.subscribe(channel, &message_callback).tap do |result| - result.callback { |reply| success_callback.call } if success_callback - end - end - - def unsubscribe(channel, message_callback) - redis_connection_for_subscriptions.pubsub.unsubscribe_proc(channel, message_callback) - end - - def shutdown - redis_connection_for_subscriptions.pubsub.close_connection - @redis_connection_for_subscriptions = nil - end - - private - def redis_connection_for_subscriptions - ensure_reactor_running - @redis_connection_for_subscriptions || @server.mutex.synchronize do - @redis_connection_for_subscriptions ||= self.class.em_redis_connector.call(@server.config.cable).tap do |redis| - redis.on(:reconnect_failed) do - @logger.error "[ActionCable] Redis reconnect failed." - end - - redis.on(:failed) do - @logger.error "[ActionCable] Redis connection has failed." - end - end - end - end - - def redis_connection_for_broadcasts - @redis_connection_for_broadcasts || @server.mutex.synchronize do - @redis_connection_for_broadcasts ||= self.class.redis_connector.call(@server.config.cable) - end - end - - def ensure_reactor_running - return if EventMachine.reactor_running? && EventMachine.reactor_thread - @@mutex.synchronize do - Thread.new { EventMachine.run } unless EventMachine.reactor_running? - Thread.pass until EventMachine.reactor_running? && EventMachine.reactor_thread - end - end - end - end -end diff --git a/actioncable/lib/action_cable/subscription_adapter/inline.rb b/actioncable/lib/action_cable/subscription_adapter/inline.rb index 81357faead..d2c85c1c8d 100644 --- a/actioncable/lib/action_cable/subscription_adapter/inline.rb +++ b/actioncable/lib/action_cable/subscription_adapter/inline.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActionCable module SubscriptionAdapter class Inline < Base # :nodoc: diff --git a/actioncable/lib/action_cable/subscription_adapter/postgresql.rb b/actioncable/lib/action_cable/subscription_adapter/postgresql.rb index e7be4c606e..50ec438c3a 100644 --- a/actioncable/lib/action_cable/subscription_adapter/postgresql.rb +++ b/actioncable/lib/action_cable/subscription_adapter/postgresql.rb @@ -1,6 +1,9 @@ -gem "pg", "~> 0.18" +# frozen_string_literal: true + +gem "pg", ">= 0.18", "< 2.0" require "pg" require "thread" +require "digest/sha1" module ActionCable module SubscriptionAdapter @@ -12,16 +15,16 @@ module ActionCable def broadcast(channel, payload) with_broadcast_connection do |pg_conn| - pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel)}, '#{pg_conn.escape_string(payload)}'") + pg_conn.exec("NOTIFY #{pg_conn.escape_identifier(channel_identifier(channel))}, '#{pg_conn.escape_string(payload)}'") end end def subscribe(channel, callback, success_callback = nil) - listener.add_subscriber(channel, callback, success_callback) + listener.add_subscriber(channel_identifier(channel), callback, success_callback) end def unsubscribe(channel, callback) - listener.remove_subscriber(channel, callback) + listener.remove_subscriber(channel_identifier(channel), callback) end def shutdown @@ -51,6 +54,10 @@ module ActionCable end private + def channel_identifier(channel) + channel.size > 63 ? Digest::SHA1.hexdigest(channel) : channel + end + def listener @listener || @server.mutex.synchronize { @listener ||= Listener.new(self, @server.event_loop) } end diff --git a/actioncable/lib/action_cable/subscription_adapter/redis.rb b/actioncable/lib/action_cable/subscription_adapter/redis.rb index 41a6e55822..c28951608f 100644 --- a/actioncable/lib/action_cable/subscription_adapter/redis.rb +++ b/actioncable/lib/action_cable/subscription_adapter/redis.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require "thread" -gem "redis", "~> 3.0" +gem "redis", ">= 3", "< 5" require "redis" module ActionCable @@ -8,9 +10,11 @@ module ActionCable class Redis < Base # :nodoc: prepend ChannelPrefix - # Overwrite this factory method for redis connections if you want to use a different Redis library than Redis. + # Overwrite this factory method for Redis connections if you want to use a different Redis library than the redis gem. # This is needed, for example, when using Makara proxies for distributed Redis. - cattr_accessor(:redis_connector) { ->(config) { ::Redis.new(url: config[:url]) } } + cattr_accessor :redis_connector, default: ->(config) do + ::Redis.new(config.slice(:url, :host, :port, :db, :password)) + end def initialize(*) super @@ -72,7 +76,7 @@ module ActionCable def listen(conn) conn.without_reconnect do - original_client = conn.client + original_client = conn.respond_to?(:_client) ? conn._client : conn.client conn.subscribe("_action_cable_internal") do |on| on.subscribe do |chan, count| diff --git a/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb b/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb index 4cce86dcca..01cdc2dfa1 100644 --- a/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb +++ b/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module ActionCable module SubscriptionAdapter class SubscriberMap |