diff options
author | Jon Moss <me@jonathanmoss.me> | 2016-02-16 12:20:03 -0500 |
---|---|---|
committer | Jon Moss <me@jonathanmoss.me> | 2016-02-18 16:26:17 -0500 |
commit | cefcc0f66e185b808fc93040b1d7805f95bf929f (patch) | |
tree | 3ad1cc881186995317d3c64d86b56c669aa9e588 /actioncable/test/client_test.rb | |
parent | 9671df3ff797347940da2e813d005a4584ef464e (diff) | |
download | rails-cefcc0f66e185b808fc93040b1d7805f95bf929f.tar.gz rails-cefcc0f66e185b808fc93040b1d7805f95bf929f.tar.bz2 rails-cefcc0f66e185b808fc93040b1d7805f95bf929f.zip |
Fix `unsubscribed` server side behavior
Before this commit, the `unsubscribed` callbacks in Action Cable server
side channels were never called. This is because when a WebSocket
"goodbye" message was sent from the client, the Action Cable server
didn't properly clean up after the now closed WebSocket. This means that
memory could possibly skyrocket with this behavior, since part of this
commit is to properly remove closed subscriptions from the global
subscriptions hash. Say you have 10,000 users currently connected, and
then all 10,000 disconnect -- before this patch, Action Cable would
still hold onto information (and Ruby objects!) for all of these now
dead connections.
Diffstat (limited to 'actioncable/test/client_test.rb')
-rw-r--r-- | actioncable/test/client_test.rb | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/actioncable/test/client_test.rb b/actioncable/test/client_test.rb index d30c381131..626b4e34a2 100644 --- a/actioncable/test/client_test.rb +++ b/actioncable/test/client_test.rb @@ -198,4 +198,25 @@ class ClientTest < ActionCable::TestCase c.close # disappear before read end end + + def test_unsubscribe_client + with_puma_server do |port| + app = ActionCable.server + identifier = JSON.dump(channel: 'EchoChannel') + + c = faye_client(port) + c.send_message command: 'subscribe', identifier: identifier + assert_equal({"identifier"=>"{\"channel\":\"EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message) + assert_equal(1, app.connections.count) + assert(app.remote_connections.where(identifier: identifier)) + + channel = app.connections.first.subscriptions.send(:subscriptions).first[1] + channel.expects(:unsubscribed) + c.close + sleep 0.1 # Data takes a moment to process + + # All data is removed: No more connection or subscription information! + assert_equal(0, app.connections.count) + end + end end |