2017-02-13 48 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

相關問題