我有一个简单的Sinatra应用程序通过Phusion Passenger运行在Apache之上。
当应用程序启动时,我启动一个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 :(得分:1)
根据您配置的乘客的方式,它可能有多个进程在运行(因此您将在每个进程中复制计算工作),或者没有(因为它可以关闭没有为某些请求提供请求的实例)时间)。
使用另一个系统来运行后台任务(如Resque或delayed_job)会更加可靠,并允许您根据您的Web请求需求配置Passenger,而与您的工作线程要求无关。
答案 1 :(得分:0)
我不太喜欢Passenger,但我认为它产生了几个服务响应的过程,因此可能无法更新和访问变量。保存和访问数据库中的数据至少应该解决该问题。对于那种情况,我个人会使用Resque和Resque Scheduler,这是一个用于创建和处理(重复)后台作业的库,这就是你现在用线程做的事情。
同样,Passenger声明具有高度的推测性,可能是错误的。
祝你好运
托拜厄斯