Rails ActiveJob и SSE: как обновить страницу после завершения вызова API
Я планирую использовать SSE для обновления страницы, на которой отображаются детали подписки Stripe.
В основном это происходит следующим образом:
- загрузить страницу сведений о подписке
- использовать задание ActiveJob для запроса деталей подписки от Stripe API
- когда задача завершена, используйте SSE, чтобы уведомить этого клиента (страницу подписки) о том, что необходимо обновить страницу.
- выполнить обновление с помощью JavaScript
У меня есть настройки кода для шагов 1 и 2 и 4, однако я не знаю, как выполнить #3.
Одна из проблем, которые я вижу, состоит в том, что ActiveJob действительно имеет обратный вызов after_perform, но встроенный в Rails SSE находится на контроллере (ActionController::Live::SSE). Я не знаю, как сделать что-то в контроллере SSE при обратном вызове after_perform.
Погуглив, я обнаружил потенциальное решение:
- Используйте плагин Sidekiq, чтобы узнать, когда задача завершена.
- Используйте PostgreSQL NOTIFY / LISTEN
Я не знаю, что будет после этого, например, как контроллер SSE узнает, что задача выполнена.
Другие заметки:
Я использую драгоценный камень Sucker Punch от Brandon Hilkert для фоновой обработки: https://github.com/brandonhilkert/sucker_punch
Я также хотел бы решение, которое не заставит меня придерживаться кода, эксклюзивного для PostgreSQL. Тем не менее, я не против, если это единственный подход, который работает.
Я также опубликовал решение Sidekiq на случай, если я не смогу сделать это с помощью sucker_punch и мне придется переключиться на Sidekiq.
Есть идеи?
Спасибо!
1 ответ
Action Cable в Rails 5 просто создан для этого типа функций. https://github.com/rails/rails/tree/master/actioncable
Action Cable выводит веб-сокеты на рельсы, что означает постоянное соединение между клиентом и сервером. Вы можете выполнять действия из клиента (javascript/coffescript) и отправлять частичные обновления json или даже html обратно клиенту. Лучший смысл того, как работает Action Cable, вы узнаете из учебника dhh https://www.youtube.com/watch?v=n0WUjGkDFS0
Создать новый канал с rails g channel
и установить объем трансляции
def subscribed
stream_from "subscription_#{current_user.id}"
end
В вашем случае шаги 1 и 2 остаются прежними. В конце шага 3. Я бы добавил ActionCable.server.broadcast "subscription_#{current_user.id}", status: payment_status
, Шаг 4. Обновите состояние на клиенте так, как вы хотели.