aboutsummaryrefslogtreecommitdiffstats
path: root/actioncable/lib/action_cable/channel
diff options
context:
space:
mode:
authorpalkan <dementiev.vm@gmail.com>2016-09-21 02:57:10 +0300
committerpalkan <dementiev.vm@gmail.com>2016-09-22 20:25:09 +0300
commit3e68d8b872b48ecb45268a7e5fcb937e68f2724f (patch)
tree6c1a25c42a8baea1141af95016abbce1f7d78469 /actioncable/lib/action_cable/channel
parent03a209e92aeed1e724b3ff787ec77936b7163ca5 (diff)
downloadrails-3e68d8b872b48ecb45268a7e5fcb937e68f2724f.tar.gz
rails-3e68d8b872b48ecb45268a7e5fcb937e68f2724f.tar.bz2
rails-3e68d8b872b48ecb45268a7e5fcb937e68f2724f.zip
Add Channel#ensure_confirmation_sent; call #subscribe_to_channel after initializing
Diffstat (limited to 'actioncable/lib/action_cable/channel')
-rw-r--r--actioncable/lib/action_cable/channel/base.rb42
-rw-r--r--actioncable/lib/action_cable/channel/streams.rb3
2 files changed, 20 insertions, 25 deletions
diff --git a/actioncable/lib/action_cable/channel/base.rb b/actioncable/lib/action_cable/channel/base.rb
index 1d9038b76a..a866044f95 100644
--- a/actioncable/lib/action_cable/channel/base.rb
+++ b/actioncable/lib/action_cable/channel/base.rb
@@ -145,22 +145,13 @@ module ActionCable
# When a channel is streaming via pubsub, we want to delay the confirmation
# transmission until pubsub subscription is confirmed.
#
- # We use atomic fixnum to track the number of waiting tasks to avoid race conditions
+ # The counter starts at 1 because it's awaiting a call to #subscribe_to_channel
@defer_subscription_confirmation_counter = Concurrent::AtomicFixnum.new(1)
@reject_subscription = nil
@subscription_confirmation_sent = nil
delegate_connection_identifiers
- subscribe_to_channel
- end
-
- # This method is called after subscription has been added to the channel.
- # Send confirmation here to avoid race conditions when client tries to perform actions
- # right after receiving confirmation.
- def registered!
- @defer_subscription_confirmation_counter.decrement
- transmit_subscription_confirmation unless defer_subscription_confirmation?
end
# Extract the action name from the passed data and process it via the channel. The process will ensure
@@ -179,6 +170,17 @@ module ActionCable
end
end
+ # This method is called after subscription has been added to the connection
+ # and confirms or rejects the subscription.
+ def subscribe_to_channel
+ run_callbacks :subscribe do
+ subscribed
+ end
+
+ reject_subscription if subscription_rejected?
+ ensure_confirmation_sent
+ end
+
# Called by the cable connection when it's cut, so the channel has a chance to cleanup with callbacks.
# This method is not intended to be called directly by the user. Instead, overwrite the #unsubscribed callback.
def unsubscribe_from_channel # :nodoc:
@@ -211,22 +213,24 @@ module ActionCable
end
end
+ def ensure_confirmation_sent
+ return if subscription_rejected?
+ @defer_subscription_confirmation_counter.decrement
+ transmit_subscription_confirmation unless defer_subscription_confirmation?
+ end
+
def defer_subscription_confirmation!
@defer_subscription_confirmation_counter.increment
end
def defer_subscription_confirmation?
- @defer_subscription_confirmation_counter.value.positive?
+ @defer_subscription_confirmation_counter.value > 0
end
def subscription_confirmation_sent?
@subscription_confirmation_sent
end
- def registered?
- @registered
- end
-
def reject
@reject_subscription = true
end
@@ -244,14 +248,6 @@ module ActionCable
end
end
- def subscribe_to_channel
- run_callbacks :subscribe do
- subscribed
- end
-
- reject_subscription if subscription_rejected?
- end
-
def extract_action(data)
(data["action"].presence || :receive).to_sym
end
diff --git a/actioncable/lib/action_cable/channel/streams.rb b/actioncable/lib/action_cable/channel/streams.rb
index c9b58f3a04..e480b93df0 100644
--- a/actioncable/lib/action_cable/channel/streams.rb
+++ b/actioncable/lib/action_cable/channel/streams.rb
@@ -84,8 +84,7 @@ module ActionCable
connection.server.event_loop.post do
pubsub.subscribe(broadcasting, handler, lambda do
- @defer_subscription_confirmation_counter.decrement
- transmit_subscription_confirmation unless defer_subscription_confirmation?
+ ensure_confirmation_sent
logger.info "#{self.class.name} is streaming from #{broadcasting}"
end)
end