views:

82

answers:

2

In Ruby, I have a controller action that immediately initiates a computationally-intensive task that takes several seconds. I want the client to poll my server and get status updates.

in my controller:

def complex_task
  Thread.new do
    loop do
      one_part_of_the_computationally_intensive_task
      # Note how much progress we've made, in case the client asks.
      save_progress
    end
  end
  # returns to client straightaway, but task continues in background.
end

def check_status
  # Retrieve state in here.
  get_progress
end

Note how check_status needs to pull state that is stored by the separate thread.

How do I write the save_progress and get_progress functions? Where do I store the state? It seems like it isn't a good idea to store it in session, since this gets sent to the client, but where else do I store it?

(related to this question, but much more general. I expect quite different answers.)

+1  A: 

You can store the status in a model, and put the status_id into the session. Alternately, you could use a database session store instead of a cookie-based one, which would keep the data you put into the session at the server side at the expense of session speed.

Tim Sullivan
+3  A: 

Take a look at delayed_job. You could easily extend this so that jobs can write progress into the delayed_jobs table, for subsequent extraction by your check_status() method (or you could even add set_status() and check_status() to delayed_job ...)

Note that delayed_job was originally extracted from Shopify; I'm guessing that this means it's had some solid real-world exposure. I'd prefer to start from a base like that than roll my own, unless I had a pretty compelling reason.

Duncan Bayne