2017-02-13 47 views
0

如何检测特定request是否仍然活动?Rails,如何知道特定请求是否仍在运行

例如,我有这样的要求UUID:

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

从另一个请求,我怎么能知道,如果以uuid ABC1233请求仍然是工作?


对于好奇:

beanstalk directives我正在使用的URL请求cron作业。

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

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

回答

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进程是否仍在运行。

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替换为您最喜欢的持久选择。

+0

我正在实现类似这样的事情,但由于请求可能死亡或者可能被杀死(在系统级别),并且“unset”信号从不发送,所以它不可信。这是因为我需要一个外部方法来知道请求是否仍然存在。 – fguillen

+0

我和你一样迷失。你显然可以在redis上节省时间戳,并定期杀死“老”的,但你可能已经知道了。让我知道如果你发现更多,这是一个有趣的问题! –

+0

检查我的答案:http://stackoverflow.com/a/42227927/316700 – fguillen

相关问题