2014-10-27 54 views
2

我有一個Play 2.3項目,我需要安排一個動作,每整整一個小時一次,所以我使用Akka將其安排在Global.onStart中。這個動作完全需要不到1個小時的時間(它會檢查數據庫中的潛在更新,然後根據它們執行一些Web請求)。Play Framework/Akka調度器延遲漂移

但是,每次除第一次運行外,都會延遲1秒。所以在60小時/更新之後,它會延遲一整分鐘,大概在9個月後它會被延遲一個小時。

起初我試着將頻率設置爲(60 * 60) - 1秒,它起初工作,但有時它會抵消,最終它運行得太晚。

看來,頻率不開始倒計時(可以這麼說),直到行動完成,這導致了這種延遲,所以我能做些什麼來防止這種漂移?

這裏我要計算延遲和調度操作的代碼:

// Time until next full hour 
static public FiniteDuration getDelay() 
{ 
    Calendar currentCalendar = Calendar.getInstance(); 

    long minute = currentCalendar.get(Calendar.MINUTE); 
    long second = currentCalendar.get(Calendar.SECOND); 
    long ms = currentCalendar.get(Calendar.MILLISECOND); 

    minute = (60L - minute) * 60 * 1000; 
    second = (60 - second) * 1000; 
    ms = 1000L - ms; 

    long delay = minute + second + ms; 

    return FiniteDuration.create(delay, TimeUnit.MILLISECONDS); 
} 

// Update once every 60 minutes 
static public FiniteDuration getFrequency() 
{ 
    return FiniteDuration.create(60, TimeUnit.MINUTES); 
} 

Akka.system().scheduler() 
    .schedule(getDelay(), getFrequency(), 
    Publisher.makeRunnable(), Akka.system().dispatcher()); 
+0

這個答案http://stackoverflow.com/questions/14145186/akka-scheduler-is-late-on-every-repeat這似乎是關於相同的問題聲稱,這是一個問題已被修復阿卡2.1 ,但我使用的是Play 2.3(不知道如何檢查我使用的Akka版本,但我相信這是更晚的版本),而且這個問題仍然存在。 – tacospice 2014-10-27 08:50:51

+0

玩2.3使用Akka 2.3,所以你應該提交一個錯誤或確保你的初始延遲計算正確。 – 2014-10-27 09:03:42

+0

似乎最初的延遲不應該有很大的差異,頻率應該仍然是第一次動作後,但它不是 – tacospice 2014-10-28 05:02:23

回答

1

的阿卡調度並不聲稱是其調度準確,因爲它只是維持一個任務隊列,它會檢查每個「打勾」(請參閱​​this page上的警告)。如果您想要準確定位您的工作,我建議您使用類似cron的庫,例如Quartz,以便您可以在正確的時間發出消息。這使您可以根據掛鐘時間更精確地安排工作,而不是依賴Akka的「打勾」概念。

+0

似乎你是對的。石英做到了。謝謝! – tacospice 2014-10-30 23:05:57

+0

很高興爲你效勞! – 2014-10-31 14:31:27

0

看來你的延遲計算到最近的整點沒有考慮到結轉:

說,目前的時間是3:58:49.999的diff來4:00:00.000是 00:01:10.001。但是,運行您的代碼將是00:02:11.001