Stimulus based ActionCable Subscriptions - possible race condition related to turbolinks preview?
Hi,
I've been upgrading a legacy app to leverage Webpacker and Stimulus with the intention of moving to Hotwire eventually too. We have a few ActionCable (AC) channels used here and there and it seems the recommended way to handle these now is via a Stimulus controller with the AC subscription being set up in the stimulus connect method and unsubscribed in the disconnect method. Makes sense and seems to always work on fresh page load.
However, if you are on a page which has such a stimulus/AC controller attached and you navigate away and back again, you will see in the browser JS console, in the cable debug section, a series of subscribe and unsubscribe events for the AC channel. Typically what I see is a single unsubscribe when leaving the page and a sequence of subscribe, confirm_subscription, unsubscribe, subscribe and confirm_subscription. I believe this is due to the turbolinks preview mechanism.
Unfortunately, every so often the above sequence is slightly different and I don't get the final confirm_subscription event and the actioncable channel does not receive any data. I can replicate this issue in both the GoRails revised tutorial source code for AC and also in a trivial fresh Rails 6.1.4.1 app which I created today.
To mitigate this issue, I am now checking during stimulus connect to see if this is a turbolinks preview and skipping the AC subscription. I then also check during stimulus disconnect to ensure that this.subscription
is defined before trying to disconnect. This results in a single unsubscribe event and a single subscribe + confirm_subscription and so far I've not been able to reproduce my original issue with this mitigation in place.
Just wondered if anyone else has seen this and maybe has a better understanding of what is happening and whether a better approach might exist?
I can post some code samples but this is my first time using this forum so wasn't sure what markdown was supported.
Thanks,
Craig.