New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ActionCable: Repeated subscription attempts #44652
Comments
Oh I guess the other solution would be to send a subscription confirmation from the actioncable server when the client asks for a subscription which is already in place, instead of swallowing it silently. That doesn’t seem like a terrible idea. Although I’m not sure if swallowing it is intentional, and solves any other issues. |
I think I'm having the same or similar problem. I tried to implement DHH's Rails 7 Blog/post demo in an application with some modifications. Mainly added a user and group that owned the post, converted the Slim, etc. I got everything working except the broadcast. I finally found the Demo Code (kinda hard to use the screencast to build code with all the jumping around) and found I had a DOM id problem. I worked in development. But then deployed it to a staging server and BOOM. If I tried to go to Discussions(post) I got a Rails 502 error. Clicking refresh would bring up the post. Trying to open another browser window would get the rails error again on the first click, the open it. I would not stream and I also had some javascript (stimulus) that was supposed to highlight some markup but it just had a blank field. In other words, nothing worked. I took out the streaming and redeployed and all other areas worked fine, just no streaming. Here are about 20 lines each of rails, nginx and puma error logs, Beyond my pay grade! |
@salex that looks unrelated to the issue I'm describing here. |
@matthewd I know you're pretty intimately familiar with action cable, do you have any advice here? |
This issue has been automatically marked as stale because it has not been commented on for at least three months. |
This is still reproducible. |
@sj26 any update on this? i have same problem to solve. multiple chat rooms, when I moved to another room, then go back to the first one or previous room, it creates another subscription with duplicated identifier: |
Update for whoever had same problem with same scenario with multiple chat rooms: I ended up using javascript to prevent creating/subscribing to server when the existing subscription already existed:
|
Check if cable is subscribed to specific channel.
|
Sorry I don't have any updates. I do think this is still an issue. We carry a patch for it in our codebase. But I don't have capacity to push it to completion myself. If someone else is keen, please let me know 🙏 |
Using this workaround for now const subscription = consumer.subscriptions.create(...createArgs)
const subscriptionExists = consumer.subscriptions["findAll"](subscription.identifier).length > 1
if (subscriptionExists) {
consumer.subscriptions["confirmSubscription"](subscription.identifier)
} |
Yeah, that's roughly the patch we carry, as proposed in #44653 🙌 |
Maybe related: hotwired/turbo-rails#173 TL;TR: I see something similar with actioncable (7.1.3.2). When I have a When "hard-reloading" the page the websocket subscription to that stream is established as expected. So this only happens when a client navigates through the page. This leads to the websocket not receiving messages anymore because the stream has been unsubscribed which leads to:
Occasionally throwing:
Imho there should be no unsubscribe at all when turbo-drive checks there is the same stream present again on the page the client navigates to. I'm still trying to understand, however this seems related. Feels a bit like a race-condition. |
Steps to reproduce
I tried creating a small reproduction script, but involving views and action cable got too complicated. Instead, here's an app which replicates it:
https://github.com/sj26/action_cable_test
It creates two subscriptions with the same identifier, with a timeout to be sure that the first subscription has already been confirmed:
Then a stream of subscription messages can be seen in the websocket traffic:
because the guarantor considers the second subscription pending:
because actioncable short circuits existing subscriptions, and so doesn't submit multiple confirmations:
https://github.com/rails/rails/blob/v7.0.2/actioncable/lib/action_cable/connection/subscriptions.rb#L32
Use case
We have a react frontend, and we want to subscribe to channels in each of the leaf components which require dynamic updates directly. Sometimes this means multiple components will be interested in the same updates, and subscribe to the same identifiers. Trying to deduplicate these subscriptions somehow requires a lot more state management which seems more fragile and uneccessary. Previous versions of actioncable before the guarantor seem to work great for this use case, and the actioncable implemenation seems to consider subscription duplication in all operations. It's the addition of the subscription guarantor in #41581 to fix #38668 which seems to have created this issue. I think it would continue to work great with some gentle adjustment.
Expected behavior
Subscribing to the same channel identifier multiple times should not constantly send subscription messages.
Actual behavior
A continuous stream of subscription messages are sent from the browser and arrive and are squashed at the server without any confirmation message returning. This taxes both the browser client and the action cable server unnecessarily.
System configuration
Rails version: 7.0.2
Ruby version: 3.1.0
Potential solution
The simplest solution seems to be to follow the pattern established in the rest of Subscriptions and avoid re-subscribing subscriptions which already exist:
#44653
It's also a little confusing. The "subscription" in the javascript environment does not necessarily have a 1:1 relationship with the "subscription" on the server. This is a good thing! But it'd be nice if they had different names.
The text was updated successfully, but these errors were encountered: