Open arusa opened 3 years ago
Hi, I encountered this issue today and confirm it exists. Maybe it's related to cable mode in cable.yml, because locally it works properly (no issue) when async mode and one puma instance. Issue exists on production where I am using Redis for cable and puma with two workers
cable.yml
development:
adapter: async
test:
adapter: test
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
puma.rb
...
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
I think it's not related to puma workers - I decreased WEB_CONCURRENCY
to 1 and the issue still exists (randomly) sometimes it works, sometimes not.
For me the issue seems to be the same, with ActionCable not confirming connection. I checked the dev tool and the stream stops working after not receiving "confirm_subscription." https://github.com/rails/rails/pull/41581
I tried using data-turbo-permanent
in various places but that doesn't seem to help.
I also having this issue:
When I have a turbo_stream_from
tag in place to connect my client to a stream and the client then navigates forth and back (using turbo-drive) to other pages where this tag is also in present, I see multiple unsubscribes
and subscribes
in my websocket monitor which occasionally leads to an unsubscribe from a stream which should be still connected.
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:
Turbo::StreamsChannel stopped streaming from ....
Occasionally throwing:
Could not execute command from ({"command"=>"unsubscribe" ....})
[RuntimeError - Unable to find subscription with identifier: ... ]
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.
Update: Still not found a solution -> however I currently deactivate turbo-drive for targets where I need a stable websocket connection with data-turbo="false"
forcing the page to be fully loaded establishing a fresh websocket connection.
I use a Stimulus controller to connect to my ActionCable channel in the connect()
hook.
I unsubscribe()
in the disconnect()
hook.
When I load my initial page, then navigate away, and then press the link to go back to the original view (not via the back button, but via a link click, hence, it's not a restoration visit), my Stimulus controller executes these functions at once:
A restoration visit works as it should.
Versions:
Simplified Stimulus controller:
import { Controller } from "@hotwired/stimulus";
import consumer from "../channels/consumer";
export default class extends Controller {
connect() {
console.log("connect");
this.channel = consumer.subscriptions.create("MyChannel", {
connected: (...args) => {},
disconnected: (...args) => {},
received: (...args) => {},
});
}
disconnect() {
console.log("disconnect");
this.channel.unsubscribe();
}
}
My whole rails website is using turbo for navigation. Subscribing to a turbo-stream using
turbo_stream_from
and then usingbroadcasts_to
to broadcast to the stream works fine on every page even when navigating with turbo (without page reloads).But when I visit a page again, after leaving it, the turbo stream on this page does not work anymore.
After leaving the page, safari shows me that an
unsubscribe
message was sent through the websocket and when I enter the page again it shows me a newsubscribe
message followed by aconfirm_subscription
message, instantly followed by anunsubscribe
message and anothersubscribe
message that doesn't get a confirmation anymore.I don't understand why this only happens at the second visit of any page that subscribes to a turbo-stream.
I have attached a screenshot of this message history:
edit:
I am running: