Rails: can I redirect from within a job?

Viewed 145

A user starts a POST request to a controller, which causes a longer flow of actions, that are network-bound and typically need 2-3 seconds to finish. After that, the user is redirected to a new page to receive the results.

As I understand it, the number of simultanously possible connections in Rails is directly connected to the number of requests blocked inside a controller. Therefore, it would be best to enqueue this action as a job and doing the redirect from there after the job is completed.

This would it make possible, to easily support a magnitude more of simultanous connections, because the handling of those jobs could be offloaded.

Is it possible in Rails, to accomplish this? Alternatively, how is it possible to scale network-bound requests for supporting many multiple simultanous connections ? And please: I don't want the client to poll, that is just not suitable for a modern web framework like RoR.

1 Answers

An alternative to polling is to use ActionCable, after client load page that contains a heavy request, for example, a checkout form, your js will automatically establish action-cable channel with particular channel id base on user session + task name, for example: heavy-task:123xyz

Now when user submit heavy task, the controller after validate will delegate to a job (with channel id heavy-task:123xyz), so this controller will free to accept another requests. After a while, the job done, this will use AcionCable to broadcast the result to the channel heavy-task:123xyz

The client will redirect to result page as soon as it receives the job message from the channel.

client1 ---- get/ load page -------> server 
    |   <------------------------200 controller
    |                                   |
establish action-cable <---------------------> Channel
    |                                   |        |
request -- post/ heavy task ------>  controller  | 
                                        |----------enqueue job --> sidekiq---
                                        |        |                          | 
                                        |        |<--------------------job done
                                        |        |
client1 <----------------------------------------- broadcast
    |                                   |        X close Channel
    ------ redirect_to get/other -----------> another-controller
                                        |           |

Note:

  • the reason the channel should establish asap after reach the form page that is the job maybe done before the establish process done (so the client will not receive job message)
  • should close channel immediately after sending job result message, since channel take much resource (memory)
  • not sure about scale since the performance will down if there're so many channels, you could consider anycable, reference
Related