2012-05-15 33 views
0

我想在非常精確的時間運行一個進程。現在我正在使用延遲作業:簡單查詢:如何在Rails中精確安排工作?

handle_asynchronously :make_live, :run_at => (exact_time_down_to_the_second) 

但它並不準確。例如,當我這樣做時:

handle_asynchronously :make_live, :run_at => (Time.now + 30.seconds) 

......它在30秒鐘+/- 15秒內執行。隨後的嘗試發生在Time.now左右的6秒鐘內,有時幾乎立即發生。

是否有確切的方法來做到這一點?不要拖延工作。

編輯

當我這樣做:

handle_asynchronously :make_live, :run_at => Proc.new {|event| event.occurs_at } 

...它運作良好,(似乎對隊列的查詢精確到秒)。即使使用短時間間隔(30秒)。

它看起來像只是控制檯測試工作不好。

這樣就解決了我現在的問題。

回答

0

延遲可能是由兩個因素造成的:延遲作業定期檢查作業。延遲作業也會按順序執行作業,所以如果隊列中已經有一些作業,它會延遲。

如果您知道並且可以提前定義任務(即與當前時間不相關),請使用Whenever寶石,它是cronjobs的包裝。

爲Delayedjobs創建一個單獨的隊列還可以減少長隊列造成的延遲。

你也可以切換到Resque,這就像內存中的隊列,它可能會以較短的時間間隔檢查隊列。

+0

我會檢查出每當。順便說一句,我只在隊列中測試一項工作;應用程序本身永遠不會超過4個,間隔一天左右。 – bevanb

0

好的。你的工作包裝對你來說不夠精確。我看到2個選項:

  1. 替換或修改作業包裝更加精確。 Resque可能會有所幫助,或者您可以在Delayed :: Job內部戳一下以更頻繁地輪詢工作。可以,但我更喜歡這種攻擊:
  2. 安排工作60秒之前,當你需要它運行。作爲參數傳遞您需要執行作業的確切時間。然後,運行sleep until Time.now == exact_time_down_to_the_second

熱潮!精確的執行,直到第二個。

+0

另外,lulalala提出了一個很好的觀點:如果你在這之前排隊工作,Delayed :: Job可能仍然無法及時趕到工作。這聽起來像是你的應用將現在的工作分開了,但是在將來,如果你有其他類型的工作,你會希望有一個這樣的重要任務的隊列,並將其他工作放在一個單獨的隊列中單獨的工作者池。 我相信Delayed :: Job現在支持命名隊列,或者Resque肯定會。祝你好運! – nthj

+0

如果您的查詢長度很長,會發生什麼情況?所有工人都會睡覺,查詢會增長。這是一個非常糟糕的主意。 –

+0

應該睡在適當實施我的解決方案的唯一工人是工作人員運行這一關鍵工作。爲了安全起見,您可以將作業封裝在超時模塊中,或者相應地調整MAX_RUN_TIME。 – nthj

0

默認情況下,延遲作業設置爲每5秒輪詢數據庫。你可以調整這個,讓它每秒輪詢一次。我對需要這種精度級別的用例感到好奇。也許有更好的解決方案?