I have a link that opens a new tab, this controller’s action would schedule a job and render a page subscribing to "pdf_rendering:#{doc_source.id}"
channel (doc source is a model, ID is UUID, not super relevant, but maybe this context is helpful)
When the job succeeds, it sends Turbo::StreamsChannel.broadcast_replace_to("pdf_rendering:#{doc_source.id}", ...)
rendering a partial that would replace my please wait...
frame with the proper contents.
This works perfectly if and only if the Job finishes after the page rendered and successfully subscribed to the channel. If the job was quick - the page renders and subscribes after the stream notification was emitted and nothing would happen.
I was thinking about a solution where I use the src
attribute on my frame, so once it loads it would send a turbo-stream request again, but it seems to be not guaranteed that the channel subscription will happen before the frame sends a request
It also seems there’s no event like turbo-stream-sunscribed
I could hook up to, and perform Turbo.visit
(instead of relying on the load using src
attribute).
What are my options? Is this an edge case not yet dealt with?
I found some topics like:
- Rails ActionCable "subscribe" race condition & fix
- How To broadcast from a background job? - #13 by BKSpurgeon
Or is there already an idiomatic way to deal with that?
Currently, I delay my job by a few seconds, I might show a “Click here to check” button to appear after some time, but those feel like half measures.
Considering long-polling as a last option, seems weird to implement such a thing when I have a working web socket connection.
Another possibility would be to record the time from before I scheduled the job, and then, in my view, subscribe to the channel and somehow get past events after the timestamp - but this feels like going against the current ActionCable architecture and philosophy.
I’m curious on what your thoughts are.