Rails,如何知道某个特定请求是否仍然 运行

Rails, how to know if a particular request is still running

如何检测特定 request 是否仍然有效?

例如我有这个请求uuid:

# my_controller.rb
def my_action
    request.uuid # -> ABC1233
end

从另一个请求中,我如何知道带有 uuid ABC1233 的请求是否仍在工作?


好奇者:

正在执行 beanstalk directives 我是 运行 使用 URL 请求的 cron 作业。

如果上一个迭代仍然是 运行,我不想开始下一个迭代。我不能只传递由请求更新的 ini/end 标志,因为请求有时会在完成之前死亡。

使用正常的 cron 任务,我使用进程的 PID 正确地管理了它。 但我认为我不能再使用 PID,因为 Web 服务器中的进程可以在不同的请求之间重用。

我不认为 Rails(或更准确地说,Rack)对此有支持,因为(据我所知)每个 Rails 请求都不知道任何其他请求.您可能会尝试访问所有 运行 线程(甚至进程),但这种实现(如果可能的话)对我来说似乎很难看 .

自己实现怎么样?

 class ApplicationController < ActionController::Base
     before_filter :register_request 
     after_filter  :unregister_request 

     def register_request 
        $redis.set request.uuid
     end

     def unregister_request 
         $redis.unset request.uuid
     end
 end

你仍然需要弄清楚如何处理异常,因为 after_filters 被跳过(也许将整个代码移动到中间件:在中间件的前阶段,它将 uuid 写入 redis 和在之后的阶段,它删除了密钥)。我敢肯定,还有很多其他方法可以实现这一目标,并且显然可以用您最喜欢的持久性选择替代 redis。

终于恢复了之前基于PID的方法

我实现了这样的东西:

# The Main Process
module MyProcess
  def self.run_forked
    Process.fork do
      SynchProcess.run
    end

    Process.wait
  end

  def self.run
    RedisClient.set Process.pid # store the PID

    ... my long process code is here
  end

  def self.still_alive?(pid)
    !!Process.kill(0, pid) rescue false
  end
end

# In one thread I can do
MyProcess.run_forked

# In another thread I can do
pid = RedisClient.get
MyProcess.still_alive?(pid) # -> true if the process still running

我可以从 Rails 请求中调用此代码,即使请求进程被重用,子进程也不会被重用,我可以监视子进程的 PID 以查看 Ruby进程还在运行.