0

我正在开发 RoR 应用程序,我需要创建一些应该与我的基础和控制器一起使用的后台服务。我有一个带有线程的类,它必须对队列做一些工作。所以我们有:

class ServerThread

   def initialize(name)
       @name = name
       @queue = Queue.new
       @thread = Thread.new do
          while true
              if @queue.empty?
                  Thread.stop
              end
              item = @queue.pop
              log = `run #{item}` 
              save_log(log)    #save into DB
          end    
       end
   end

   def add_to_queue(item)
       @queue << item
       @thread.run
   end

end

现在它就像这样工作。我只是在某个文件中创建全局变量:

$threads = SomeService.new
Server.all.each do |server|                    #servers from DB
    $threads << ServerThread.new(server.name)
end

有时浏览器用户通过控制器将项目添加到队列中:

class ServerController < ApplicationController

   def add_to_queue       
       $threads.get_thread_by_name(params['server']).add_to_queue(params['item'])       
       render :nothing => true
   end    

end

我有一些用户将项目添加到队列中,我需要监视我的应用程序上的所有线程。我需要在启动我的 rails 应用程序时创建这个 $threads,并且这个线程应该对所有浏览器用户都是通用的。现在我尝试使用 apache2 和乘客部署我的应用程序,所以这个全局变量不起作用!

没有全局变量怎么办?

RoR 3.2,红宝石 1.9.2

4

1 回答 1

0

就像@Sergio 已经说过的那样。最好不要从头开始写这样的东西。可靠地编写并发程序并不是最简单的任务之一,而且很难调试。红宝石中有一些非常好的替代品。看看 ruby​​ 工具箱:https ://www.ruby-toolbox.com/categories/Background_Jobs

如果你真的想自己做,那么你必须用可以由同一台甚至不同机器上的多个进程共享的东西替换你的全局变量。我认为这个问题的一个非常简单的解决方案是使用redis的排队功能并在此基础上实现你的后台工作人员。

于 2013-10-14T14:05:26.307 回答