Rails 5 ActionCable issue with running multiple feeds for a web socket

snlamm , and I had a problem with implementing multiple web socket channels in our Rails application. The error is that the server freezes after the answer below:

Started GET "/cable" for ::1 at 2016-05-24 11:42:16 -0400 Started GET "/cable/" [WebSocket] for ::1 at 2016-05-24 11:42:16 -0400 Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket) 

Note. There are no errors in our browser console. We are using Chrome v 50.0 (latest version).

However, on an inconsistent basis, if we restart both our browsers and servers, we will get:

 Started GET "/cable" for ::1 at 2016-05-24 11:45:54 -0400 Started GET "/cable/" [WebSocket] for ::1 at 2016-05-24 11:45:54 -0400 Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket) ItemsChannel is transmitting the subscription confirmation ItemsChannel is streaming from items MessagesChannel is transmitting the subscription confirmation MessagesChannel is streaming from messages 

and everything is working fine.

As already mentioned, this fix is ​​inconsistent and most often our server freezes. We noticed that there is no problem when we have only one channel.

Here is our code for the item channel, which is one of the two channels we added. The code for both channels is almost identical:

way

 mount ActionCable.server => '/cable' 

Channels / application _cable / channel.rb

 module ApplicationCable class Channel < ActionCable::Channel::Base end end 

Channels / application _cable / connection.rb

 module ApplicationCable class Connection < ActionCable::Connection::Base end end 

<strong> Channels / items _channel.rb

 class ItemsChannel < ApplicationCable::Channel def subscribed stream_from 'items' end end 

view / orders / show.html.erb

This is our view of the channel attached to the item’s display.

 <div id="item-list"> <h2>Items: <% @order.items.each do |item| %></h2> <li><%= item.name %> - $<%= item.cost %></li> <% end %> </div> </ol> <div id="item-errors"> </div> <br> <h3>Time until ordered: <%= ((@order.expiration - @order.date_ordered) / 60).round %> minutes</h3></div> <%= form_for @item, remote: true do |f| %> <%= f.hidden_field :order_id, value: @order.id, id: "order-id" %> <span id='item-content-reset'> Item name: <%= f.text_field :name, id: 'item-name' %> Cost: <%= f.text_field :cost, id: 'item-cost' %> </span> <%= f.submit "Add Item", :id => 'item-create-btn' %> <% end %> </div> 

Controllers / items _controller.rb

 class ItemsController < ApplicationController def create @item = Item.new(item_params) @item.user = @current_user if @item.save ActionCable.server.broadcast 'items', name: @item.name, cost: @item.cost head :ok else error_message = @item.errors.messages render partial: 'shared/errors', locals: { errors: flash.now[:alert] = "Item " + error_message[:name][0] } end end private def item_params params.require(:item).permit(:order_id, :cost, :name) end end 

assets /application.js

 //= require jquery //= require bootstrap-sprockets //= require jquery_ujs //= require bootstrap-switch // require jquery.session // require turbolinks //= require_tree . 

<strong> assets / javascripts / channels / chatrooms.js

 //= require action_cable //= require_self //= require_tree . this.App = {}; App.cable = ActionCable.createConsumer("/cable"); 

<strong> assets / javascripts / feeds / items.js

 App.items = App.cable.subscriptions.create('ItemsChannel', { received: function(data) { return $("#item-list").append(this.renderItem(data)); }, renderItem: function(data) { return "<li> " + data.name + " - " + "$" + data.cost + "</li>"; } }); 

After the end of the server we will use aux | grep for rails, ruby, puma, redis, and they all closed successfully (i.e. there were no zombie processes). What can cause a server to freeze?

+5
source share
1 answer

This sounds like the following error ( Actioncable deadlock with multiple channels # 24741 ). You can get the patch from the previous link. If you work in development, you can also try setting config.eager_load = true in development.rb, which worked for me.

+1
source

All Articles