Rails,如何知道特定请求是否仍在运行

时间:2017-02-13 15:47:45

标签: ruby-on-rails cron request uniqueidentifier

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

例如,我有这个请求uuid:

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

从另一个请求中,我怎么知道uuid ABC1233的请求是否仍然有效?

对于好奇:

关注beanstalk directives我正在使用网址请求运行cron作业。

如果上一次迭代仍在运行,我不想开始下一次迭代。我不能仅仅在请求更新的ini/end标志中进行中继,因为请求有时会在完成之前消失。

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

2 个答案:

答案 0 :(得分:0)

我不认为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。

答案 1 :(得分:0)

最后,我恢复了以前基于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进程是否仍在运行。