Handling Rails Background and Batch Jobs with BackgrounDRb

Posted by Daniel Butler Tue, 23 May 2006 11:20:00 GMT

Example Worker class code:

class FooWorker
  include DRbUndumped

  def initialize(options={})
    @progress = 0
    @results = []
    @options = options
    start_working
  end

  def start_working
    # Work loop goes inside a new thread so it doesn't block
    # rails while it works. A neat way to do progress bars in
    # the browser is to have a @progress instance var that is
    # initialized to 0 and then gets bumped up by your long 
    # running task. This way you can poll for the progress
    # of your job via ajax and update a client side progress bar.
    Thread.new do
      # main work loop goes here. do work and update the
      # progress bar instance var.
      while something
        @results << foo(@options)
        @progress += 1
        break if @progress > 99
      end
    end  
  end

  def results
    @results
  end

  def progress
    puts "Rails is fetching progress: #{@progress}" 
    @progress
  end      
end

Example controller code:

# start new worker and put the job_key into the session so you can 
# get the status of your job later.
def background_task
  session[:job_key] = MiddleMan.new_worker(:class => :foo_worker,
    :args => {:baz => 'hello!', :qux => 'another arg!})
end

def task_progress
  if request.xhr?
    progress = MiddleMan.get_worker(session[:job_key]).progress
    render :update do |page|
      page.replace_html(
        'progress', 
        "<h3>#{progress}% done</h3>" +
        "<img src='/images/progress.gif' " +
        "width='#{progress * 2}' height='15' />")
      if progress == 100
         page.redirect_to :action => 'results'
      end   
    end 
  else
    redirect_to :action => 'index'   
  end
end

def results
  @results = MiddleMan.get_worker(session[:job_key]).results
  MiddleMan.delete_worker(session[:job_key])
end

BackgrounDRb installs as a plugin, and all code resides within your Rails application. Because it can communicate to remote servers via DRb, you can launch your long-running tasks on other machines if necessary. It looks like it’ll soon become a very useful framework for building Rails front-ends to existing applications, and for handling user interaction with batch processes.

Enjoy.

Posted in  | 2 comments

Sponsored Links

Sponsored Links

Comments

  1. Avatar Daniel said 4 days later:
  2. Avatar Brent said 198 days later:

(leave url/email »)

   Comment Markup Help Preview comment