How To broadcast from a background job?

I have a session where a user is clicking buttons on the front-end. A click is accepted by the controller, and spawn a Sidekiq background job. At this point the controller updates the screen using a Turbo response. I would like to also update the screen inside the background job. Is there a way to connect the background job to the turbo stream set for this user session?

Wow. Who knew such a simple question had no answer. I can only assume it either no one uses Turbo and background jobs, or it truly is stunningly easy to broadcast a message from a job to a specific browser session.

Or quite frankly, this is impossible, and I should forget it and move on. Can any who has dabbled with this please comment and help a guy out a little bit?

You can broadcast a TurboStream (from the affected model) and if you’ve registered a turbo-stream on the page, it will do whatever you configured that broadcast to do (prepend, append to a collection; replace; remove) in any page that is still connected to the server and listening for cable traffic. Turbo-Frames respond to a browser request, not a background server request. Once you queue a job in the background, the request is over, and there can be no further reply.

Walter

Ok thanks. So unless the background job affects a model, there is no hope of updating from a job. Good to know.

Not correct. Models have convenience methods to make it easier, but you can broadcast without a model using Turbo::StreamsChannel.

Alert ALL users

<%= turbo_stream_from :alerts %>
Turbo::StreamsChannel.broadcast_render_to(:alerts, target: 'alerts', partial: 'alerts/my_partial', locals: { message: alert.message })

However, models do help limit the scope as to who receives the broadcast. For example, only broadcast alerts to a specific user

Alert Specific users

<%= turbo_stream_from current_user.id, :alerts %>
# alert specific user
Turbo::StreamsChannel.broadcast_render_to(@alert.user_id, :alerts, target: 'alerts', partial: 'alerts/my_partial', locals: { message: @alert.message })

Ahhh, so maybe this will work? All my templates have a current_shop. The background job works on a current shop in the sense that it will do work on behalf of the shop. So if in my template where a button was clicked to inform the server “hey server, start a job”, if I have a turbo element as in

<%= turbo_stream_from current_shop, :alerts %>

and when my background job ends, I then run a

Turbo::StreamChannel.broadcast_render_to(current_shop, :alerts, target: 'alerts', partial: 'alerts/my_partial', locals: {message: 'Job completed'}

That would present an alert on the screen with that message? I am going to have to try that out. If that works, that is pretty cool.