[Rails] Re: Re: script/server lighttpd on Windows

Zed Shaw
Thu, 27 Apr 2006 02:59:54 -0000

On 4/26/06 3:38 PM, "Alex Wayne"
<rubyonrails@beautifulpixel.com> wrote:

>> I''m curious.  What''s your reason for wanting to use
lighty for
>> development?
>
> Well not specifically lighty I guess, just something faster than
> webrick.  And not only is webrick slow but single threaded, and my app
> has a few long running actions that report their progress via ajax
> calls.  The problem is that since Webrick is single threaded it cant
> process the ajax calls while the long running action is working.
> Currently I actually have to upload it the server in order to test it,
> causing unnecesary svn commits.
>
> I''ll see if mongrel can tickle my fancy.
>

Sorry Alex, not matter what Rails has to get locked.  If you have very long
running processes and need to give updated status, there''s a pattern
you
should probably look into.  Basically, you offload the real work to a DRb
server (they''re trivial to write).  The DRb server then gives you
status on
the job which you report via Ajax.  When the work is done you collect the
result from the DRb server and display it.

Here''s a basic kind of pseudo code (which I''ve *got* to write
up soon):

 def setup_work
  worker = WorkerClient.new(host, port)  # you write this client with DRb
  ticket = worker.dowork("blah")
  session[:ticket] = ticket
 end

 def ajaxy_worker_done_check
  worker = WorkerClient.new(host, port)

  if worker.is_done(session[:ticket])
    render :partial => "worker_done"
  else
    render :partial => "worker_not_done"
  end
 end

 def work_done
  results = worker.get_results(session[:ticket])
 end

None of that will work out of the box, just kind of there to give you an
idea.  WorkerClient would be a simple DRb client that you''d connect to
a DRb
server that receives work commands.  DRb is ultra easy so don''t be
afraid.

In setup_work you get the worker to dowork and it returns a little ticket
(probably just a simple integer ID) that you can use later to poll for
results.

You browser then uses some nifty ajax to hit the ajaxy_worker_done_check.
All this action does is fire up a WorkerClient and ask the worker if the job
with the given ticket is done yet.  When it''s not you return the right
partial to keep the ajax going.  If it is you return the partial that makes
the ajax progress go to the work_done action.

At the work_done action you simply take the ticket and get the results.

There''s about a billion variants of this technique, but the idea is
that the
setup_work action gets out right away, the work is offloaded to another
server to do the waiting and crunching, and the results are collected later.
This keeps your Rails nice and snappy.

But, the real benefit of this is that you can actually move *all* of this
code out to a snazzy ultra fast Mongrel handler and not even use Rails.  You
might have to use rails in the setup_worker and most definitely in
work_done, but in the ajaxy_worker_done_check it would only be using DRb so
no need to hook up rails.  Only change you''d have to make is to pass
the
ticket in via a Mongrel Handler''s request params rather than using the
session (which also makes this stateless).

Well, good luck.

Zed A. Shaw