7

I need to do request on remote service after rendering the page

My controller:

after_filter :remote_action, only: :update

def update
  @res = MyService.do_action foo, bar
  return render json: @res[:json], status: @res[:status] unless @res[:success]
end

def remote_action
  # There is remote http request
end

I need to call remote_action method after rendering the page

Gleb Vishnevsky
  • 547
  • 8
  • 16
  • Not sure why you need to do this? Can you give more background on why it needs to be called after, and not during? You could make an api call via js that triggers this action after the page has rendered on the client side. – penner Oct 20 '15 at 15:38
  • It takes some time to make request on remote server, and I need to call this action in background, for example: sending tweets via twitter api – Gleb Vishnevsky Oct 20 '15 at 15:53

1 Answers1

9

after_filter is run after the template has been converted into html, but before that html is sent as a response to the client. So, if you're doing something slow like making a remote http request, then that will slow your response down, as it needs to wait for that remote request to finish: in other words, the remote request will block your response.

To avoid blocking, you could fork off a different thread: have a look at

https://github.com/tra/spawnling

Using this, you would just change your code to

def remote_action
  Spawnling.new do
    # There is remote http request
  end
end

The remote call will still be triggered before the response is sent back, but because it's been forked off into a new thread, the response won't wait for the remote request to come back, it will just happen straight away.

You could also look at https://github.com/collectiveidea/delayed_job, which puts jobs into a database table, where a seperate process will pull them out and execute them.

Max Williams
  • 32,435
  • 31
  • 130
  • 197