2011-09-21 82 views
1

我有一个简单的Sinatra应用程序,通过Phusion Passenger在Apache上运行。Sinatra和Phusion乘客的线程行为

当应用程序启动时,我启动一个Ruby线程,每分钟执行一次繁重的计算,将结果留在全局变量中(然后在其他位置访问)。

当使用rackup时,该变量每分钟更新和刷新一次,但在Passenger下运行时,似乎没有这样做。

# Seed the initial license data - on Sinatra starting - and 
# set it on a global variable. 
$license_data = generate_license_data(360) 

# Start up a worker thread that will update the license data 
# every 60 seconds. This thread will run until termination 
# of the parent thread. Only this thread will modify the values 
# of the global variable "license_data". 
worker_thread = Thread.new do 
    while true 
    sleep 60 
    t = Time.now 
    print "Generating license data ..." 
    $license_data = generate_license_data(360) 
    print " OK (#{seconds_to_string(Time.now-t)})\n" 
    end 
end 

# Generate the actual HTML snippet we need for the license entry 
# by accessing the global variable "license_data". 
def generate_license_entry 
    # The license block. 
    @licensechart = {} 
    @licensechart[:values] = $license_data[:values_string] 
    # Generate the table entry. 
    haml :license 
end 

任何想法?我也很乐意知道另一种缓存计算的更好方法,以及如何每分钟更新一次。

+0

嗯。我现在看着[delayed_job](http://rubygems.org/gems/delayed_job),正如SO提出的[question](http://stackoverflow.com/questions/3268832/is-it-a-坏主意到创建工作者线程-IN-A-服务器进程)。 – Dan

回答

0

我并不十分注意Passenger,但我认为它产生了几个服务响应的过程,因此可能无法更新或访问该变量。保存和访问数据库中的数据至少应解决该问题。对于这种情况,我个人会用ResqueResque Scheduler,这是一个用于创建和处理(循环)后台作业的库,这是您现在使用线程执行的操作。

而且,乘客声明具有高度推测性,可能是错误的。

问候

托比亚斯

1

根据已配置的乘客怎么样,它可能需要在运行(所以你会复制每个进程中的计算工作)多个进程,或无(如它可以关闭一段时间内未处理请求的实例)。

使用另一个系统来运行后台任务(比如Resque或delayed_job)会更可靠,并且允许您根据您的Web请求需求配置Passenger,而与您的工作线程要求无关。