Hi,
I’m using the BackgroundRb scheduler (http://
backgroundrb.rubyforge.org/172) w/ rails (I’m using the older version
– not the 1.0 release announced yesterday).
My understanding of BackgroundRb is that it creates a separate thread
(divorced from http request/response) that can run a long-running
process (LRP).
The idea is to allow a rails application to periodically check on the
status of the LRP and (potentially) provide updates on a web-page to a
user.
There is a bit of sample-code for BackgroundRb (http://www.infoq.com/
articles/BackgrounDRb) that demonstrates how the status of a LRP can
be checked.
Here is sample-code from a worker class described in the link shown
above:
class FooWorker < BackgrounDRb::Rails
attr_reader :progress
def do_work(args)
@progress = 0
calculate_the_meaning_of_life(args)
end
def calculate_the_meaning_of_life(args)
while @progress < 100
calculations here
@progress += 1
end
end
end
FooWorker functions properly in my hands (i.e. a sample web-page will
gradually show an increase in the value of @progress up to 100%).
The problem, however, happens when I change the code in the method
called calculate_the_meaning_of_life(args) found within FooWorker to
have it write a large file. The idea is to have rails/the-web-page
check on the status of the file-writing until it is completely done.
The problem is that the file-writing method seems to lock the
@progress variable and I can’t access @progress via my controller/
periodical-updater until the entire
method (calculate_the_meaning_of_life(args)) is complete.
The method shown below (where I write a file) doesn’t give me access
to @progress until the file is completely written & closed.
This is part of my new FooWorker class file
1 def calculate_the_meaning_of_life(args)
2 e = Event.find_all_by_id(best, :limit => 500000)
3 @progress = 0.0
4 @file_name = “#{args[:user_name]}.csv”
5 open(“/e1/public/csvs/#{@file_name}”, “w”)
6 e.each_with_index do |row, i|
7 f.puts((columns.map {|c| row.send(c[:accessor])}).join(“$”))
8 @progress = 100.0 * (i.to_f / e.size.to_f)
9 end
10 end
11 @progress = 100
12 end
13 FooWorker.register
if I delete lines 5 and 10 (i.e. I remove the file-writing commands,
then I have access to the @progress variable even while I’m iterating
through the result set (e.each_with_index {|blah| blah blah }), but
lines 5 and 10 block access.
Clearly, I’m doing something wrong (perhaps using the wrong file i/o
method), but I’m not sure of how to fix the problem.
Any suggestions or explanations as to what I’m doing wrong are much
appreciated.