I am planning to use SSE to update a page that shows Stripe subscription details.
Basically it goes as follows:
- load subscription detail page
- use an ActiveJob job to request subscription details from Stripe API
- when task is finished, use SSE to notify that client (the subscription page) that an update is to be made to the page
- perform the update via javascript
I have code setup for steps 1 and 2 and 4, however, I do not know how to perform #3.
One of the problems that I see is that an ActiveJob indeed has an after_perform callback, but the SSE built in Rails resides on the controller (ActionController::Live::SSE). I do not know how to do something in the SSE controller on the after_perform callback.
Googling, I found out a potential solution:
- Use a Sidekiq plugin to be able to tell when a task is finished.
- Use PostgreSQL NOTIFY / LISTEN
I don't know what goes after that, like how would the SSE controller know that the task is performed.
Other Notes:
I am using Brandon Hilkert's Sucker Punch gem for background processing: https://github.com/brandonhilkert/sucker_punch
I would also like a solution that will not force me to stick with PostgreSQL-exclusive code. However, I do not mind if that's the only approach that works.
I also posted a Sidekiq solution in case I can't do it with sucker_punch and would have to switch to Sidekiq.
Any ideas?
Thanks!
Action Cable in Rails 5 is just build for this type of features. https://github.com/rails/rails/tree/master/actioncable
Action Cable brings web sockets to rails, which means persisted connection between client and server. You can perform actions from client (javascript/coffescript) and push json or even html partial updates back to the client.The best sense of how Action Cable works you will get from dhh tutorial https://www.youtube.com/watch?v=n0WUjGkDFS0
Generate new channel with
rails g channel
and set a scope of broadcastIn your case steps 1 and 2 stays the same. On the end of the step 3. I would add
ActionCable.server.broadcast "subscription_#{current_user.id}", status: payment_status
. Step 4. update state on client as you wanted to do.