Closed adam-h closed 1 year ago
Hey @adam-h!
Thanks for the detailed report!
Looks like a bug in the @anycable/core
library (I'll transfer the issue there).
Strangely I still see subsequent live broadcast messages in the websocket messages of the dev tools even after this error
That's not strange: from the server point of view, there is a subscription, so you continue receiving updates (the history request is confirmed—that indicates that the subscription is alive at the server side).
The actual question is why does the client tries to send the subscribe
command again? It should not. It would be helpful if you can share the full WS log (some important pieces are not visible on the screenshots, like full identifiers and restore_ids from the welcome message). Even better if you can enable debug logging at the client side (createCable({logLevel: 'debug', ...})
) and share the logs.
@palkan Thanks for getting back to me and putting this in the right place. Attached are the full logs of me reproducing this.
Thanks for the logs. The relevant part is here:
// Looks like page refresh / DOM update triggered unsubscription from all streams
// In anycable-client, we synchronize subscribe/unsubscribe commands to the same channel to prevent concurrent commands; so we try to acquire the lock here
@anycable--web-731193.js:1 acquiring unsubscribe lock {identifier: '{"channel":"ActivityVisualizationChannel","signed_…42272f7d8d35c5c5e0d00f34ca156a49c614ceda5c77b0f"}'}
// New HTML brings back the same `turbo-stream-source` elements, initiating the subscription (again, trying to acquire the corresponding locks)
@anycable--web-731193.js:1 acquiring subscribe lock {identifier: '{"channel":"ActivityVisualizationChannel","signed_…42272f7d8d35c5c5e0d00f34ca156a49c614ceda5c77b0f"}'}
// The lock has been granted for the unsubscribe command...
@anycable--web-731193.js:1 unsubscribe lock has been acquired {identifier: '{"channel":"ActivityVisualizationChannel","signed_…42272f7d8d35c5c5e0d00f34ca156a49c614ceda5c77b0f"}'}
// However, we detect that it's no longer needed—we want to subscribe! So, we cancel this command
@anycable--web-731193.js:1 cancel unsubscribe, no longer needed {identifier: '{"channel":"ActivityVisualizationChannel","signed_…42272f7d8d35c5c5e0d00f34ca156a49c614ceda5c77b0f"}', intent: 'subscribed'}
// Now, the subscribe lock has been granted
@anycable--web-731193.js:1 subscribe lock has been acquired {identifier: '{"channel":"ActivityVisualizationChannel","signed_…42272f7d8d35c5c5e0d00f34ca156a49c614ceda5c77b0f"}'}
// And here is the problem — we don't check that we're already subscribed and must cancel this operation
@anycable--web-731193.js:1 subscribing {identifier: 'ActivityVisualizationChannel', params: {…}}
@anycable--web-731193.js:1 outgoing message {command: 'subscribe', identifier: '{"channel":"ActivityVisualizationChannel","signed_…42272f7d8d35c5c5e0d00f34ca156a49c614ceda5c77b0f"}', history: {…}}
I will try to publish a fix asap
Released a fix in @anycable/core
0.7.10. Please, let me know, if it helped.
@palkan Thank you so much, this is great! Really appreciate your help on this.
Verified it's resolved my issue (manually applied the same patch to my local package as 0.7.10
isn't published yet).
Tell us about your environment
npm packages:
@anycable/turbo-stream
@ 0.4.0@anycable/core
@ 0.7.9@anycable/web
@ 0.7.3AnyCable-Go version:
anycable-go-pro:1.4.6-alpine
AnyCable gem version:
anycable-rails (1.4.0)
anycable (1.4.3)
What did you do?
Trying to setup reliable streams and it's initially working then failing after a short period of time when reconnecting.
118.0.5993.117
) as the client I am letting it connect to anycable and confirm it's receiving broadcast messages from my rails application.failed to subscribe
errorWhat did you expect to happen?
Reconnection works, historical messages are received and new broadcasts continue to function indefinately.
What actually happened?
I get a
SubscriptionTimeoutError: Haven't received subscription ack in 10000ms for {"channel":"...","signed_stream_name":"...}
error ~10s after I go back online.Up until this error I still receive new live broadcasts. Strangely I still see subsequent live broadcast messages in the websocket messages of the dev tools even after this error - they are just not processed at all by the client, I assume they're just ignored as it thinks the subscription is dead.
Browser console log:
Websocket browser messages:
Note how it is trying to subscribe again, even though the backend thinks it already is
From the anycable go service (debug enabled):
The backend thinks the client is still subscribed. It does even keep sending messages 'correctly' over the websocket (which are ignored).
Similar to https://github.com/anycable/anycable-go/issues/141 and https://github.com/anycable/anycable-go/pull/142