2011-06-09 84 views
4

我有一個玩!框架工作執行每30秒:使用Play併發運行計劃作業!框架

@Every("30s") 
public class MyJob extends Job { ... } 

這個工作做了一些事情,如閱讀電子郵件和書面形式向DB。但是,該作業可能在30秒內未完成。如果工作時間超過30秒,我想後續工作,試圖在原工作仍在進行時開始。有沒有辦法做到這一點?甚至是暫停後續作業,直到原作完成?

回答

10

據我所知,你不必殺死這份工作。我創造了一份工作,而不是必須每分鐘運行一次,但在某些情況下,它可能(可能)運行超過一分鐘。

我做了一些測試,並且知道我可能以錯誤的方式完成了它們,但是如果它已經在運行,則Play不會啓動新的Job實例。作業完成後,它會在預期的時間內運行下一個實例。就好像Play將Jobs視爲「Singletons」一樣,只有給定類型的某個類型在給定時間處於活動狀態。

所以,不,你不需要殺或檢查任何東西。真棒,不是嗎? ;)

+0

是的,實際上看起來是這樣!謝謝Pere。 – digiarnie 2011-06-14 06:19:17

1

您可以使用ReentrantLock來防止多個實例一次運行。事情是這樣的:

@Every("30s") 
public class MyJob extends Job { 
    /** 
    * Used to avoid running multiple instances of this job simultaneously. 
    */ 
    private static final ReentrantLock runningLock = new ReentrantLock(); 

    @Override 
    public void doJob() { 
    // sb: try to acquire the lock. if the lock is in use, then just 
    // return immediately, because this job is already running. 
    // wait a half second before giving up. 
    if (!runningLock.tryLock(500, TimeUnit.MILLISECONDS)) { 
     // maybe log a message here? 
     return; 
    } 

    // IMPORTANT: ANY CODE ADDED TO THIS METHOD MUST BE INSIDE THE TRY OR 
    // YOU RUN THE RISK OF FAILING TO RELEASE THE LOCK! 

    try { 
     // perform your job code here... 
    } finally { 
     // sb: we're finished; release the lock 
     runningLock.unlock(); 
    } 
    } 
} 

鑑於你的工作,每30秒運行一次,沒有任何理由,而另一個正在運行延誤工作 - 只是取消。