Sinatra和Phusion Passenger中的线程行为

时间:2011-09-21 10:05:32

标签: ruby sinatra passenger

我有一个简单的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

有什么想法吗?我也很高兴知道一种替代的,更好的缓存计算方法,以及如何每分钟更新一次。

2 个答案:

答案 0 :(得分:1)

根据您配置的乘客的方式,它可能有多个进程在运行(因此您将在每个进程中复制计算工作),或者没有(因为它可以关闭没有为某些请求提供请求的实例)时间)。

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

答案 1 :(得分:0)

我不太喜欢Passenger,但我认为它产生了几个服务响应的过程,因此可能无法更新和访问变量。保存和访问数据库中的数据至少应该解决该问题。对于那种情况,我个人会使用ResqueResque Scheduler,这是一个用于创建和处理(重复)后台作业的库,这就是你现在用线程做的事情。

同样,Passenger声明具有高度的推测性,可能是错误的。

祝你好运

托拜厄斯