robskrob
robskrob

Reputation: 2918

Action Cable error Could not execute command from...RuntimeError - Unable to find subscription with identifier

I am running into an error when make a call to perform upstream to an Action Cable channel, 'UsersChannel'. This is the complete error message:

Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"UsersChannel\"}", "data"=>"{\"id\":\"1\",\"action\":\"show\"}"}) [RuntimeError - Unable to find subscription with identifier: {"channel":"UsersChannel"}]: /Users/robskrob/.rvm/gems/ruby-2.4.1/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:76:in find' | /Users/robskrob/.rvm/gems/ruby-2.4.1/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:53:inperform_action' | /Users/robskrob/.rvm/gems/ruby-2.4.1/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:17:in execute_command' | /Users/robskrob/.rvm/gems/ruby-2.4.1/gems/actioncable-5.1.4/lib/action_cable/connection/base.rb:85:indispatch_websocket_message' | /Users/robskrob/.rvm/gems/ruby-2.4.1/gems/actioncable-5.1.4/lib/action_cable/server/worker.rb:58:in `block in invoke'

This is very bizarre because in the same file I successfully use the subscribed channel to perform upstream to create a user (usersChannel.perform('create', {...})). Why am I seeing the above error when I make a different call on the same subscriber that I used to create a user? It was able to find the UsersChannel subscription previously when calling UsersChannel#create. Why is it throwing this error when calling UsersChannel#show with usersChannel.perform('show', {...})on the front end?

Upvotes: 2

Views: 1621

Answers (2)

Pragya Sriharsh
Pragya Sriharsh

Reputation: 559

In my case, race condition arises between two streaming channels. I do resolve this issue by adding

stop_all_streams

whenever 'unsubscribed' methods called.

 def unsubscribed
   #Unsubscribes all streams associated with this channel from the pubsub queue.
    stop_all_streams
 end

Upvotes: 0

robskrob
robskrob

Reputation: 2918

I solved this problem by creating a HTTP REST client to make the request for a user. In other words, when the route in the browser is, localhost:3000/user/1, the exported action loadUser makes a RESTful request to the server to a response containing the user data, which is what I need the app to do when the above route is drawn.

The problem with my original approach was the following: in the file that I at the same time make an upstream call to get a user and establish a connection to the UsersChannel the call to get the user happens before an actual connection between the server and the client is established, regarding the UsersChannel. Before actioncable can make any upstream call successfully the following must happen first: "UsersChannel is streaming from users_channel".

In short, my app was performing upstream with a create subscription before the stream was established so the call out to the server, UsersChannel#show, could not succeed. I guess you could call the root of the problem which I experienced, a race condition: the upstream call beat out the establishing of a connected stream between the client and the server.

Lesson learned: use HTTP when the client needs to receive data on full page reloads. Calls via actioncable may not have the stream established between the client and the server for the upstream call to succeed.

Upvotes: 1

Related Questions