09.異步Jobs

09.異步Jobs

因爲play是一個web應用程序,因此許多應用程序邏輯都是由控制器返回給http請求的。

但有些時候,我們需要在http請求外執行一些應用邏輯。比如非常有用的初始化任務,維護任務或運行不能被http請求池中斷的長時運行的任務等等。

Jobs可以被框架全面進行管理。意思是play負責管理所有的數據庫連接原料stuff,JPA實體管理器負責管理數據同步和事務管理。要想創建一個job,只需要繼承play.jobs.Job即可。

package jobs;

 

import play.jobs.*;

 

public class MyJob extends Job {

   

    public voiddoJob() {

        //在這兒執行某些邏輯

    }

   

}

有些時候需要任務返回結果,這時就需要重載doJobWithResult()方法。

package jobs;

 

import play.jobs.*;

 

public class MyJob extends Job<String> {

   

    public String doJobWithResult() {

        //在這兒執行某些邏輯

        returnresult;

    }

   

}

本示例僅使用了String作爲返回類型,當然可以返回任何對象類型。

引導程序任務Bootstrap jobs

引導程序任務會在play應用啓動時執行。要想實現該任務,只需要在你的任務上添加@OnApplicationStart註釋:

importplay.jobs.*;

 

@OnApplicationStart

public classBootstrap extends Job {

   

    public void doJob() {

        if(Page.count() == 0) {

            new Page("root").save();

            Logger.info("A root page hasbeen created.");

        }

    }

   

}

注意:在這裏不需要返回結果,即使這樣做了,結果也會丟失。

默認情況下,所有標識爲@OnApplicationStart的任務都將以隊列方式執行。當所有的job執行結束後,應用程序才正式啓動並開始處理請求。

如果你打算讓你的任務在應用程序啓動時執行,但你又想立即管理進行請求處理,那麼可以使用@OnApplicationStart(async=true)註釋。然後,你的job將在後臺啓動。

警告!


當運行於DEV模式時,應用程序將在第一個請求到達時才啓動。此外,在DEV模式時,在需要的時候,應用程序會自動重啓。

當運行於PROD模式時,應用程序將和服務器一起同步啓動。

預定義任務Scheduled jobs

預定義任務由框架週期性執行。你可以使用@Every註釋要求play在一個特定的週期內運行job。

importplay.jobs.*;

 

@Every("1h")

public classBootstrap extends Job {

   

    public void doJob() {

        List<User> newUsers =User.find("newAccount = true").fetch();

        for(User user : newUsers) {

            Notifier.sayWelcome(user);

        }

    }

   

}

如果@Every註釋還不足以滿足需要,你可使用帶有CRON表達式的@On註釋來運行你的job。

importplay.jobs.*;

 

/** Fire at 12pm(noon) every day **/

@On("0 0 12 ** ?")

public classBootstrap extends Job {

   

    public void doJob() {

        Logger.info("Maintenance job...");

        ...

    }

   

}

小建議

我們是使用Quartzlibrary來解析CRON表達式的。

你不能返回結果,即使這樣做了,結果也會被丟棄。

觸發任務job

調用Job實例的now()方法可以在任何時候觸發job來執行一段特定的任務。這個時候,job將以非阻塞方式立即執行。

public static voidencodeVideo(Long videoId) {

    new VideoEncoder(videoId).now();

    renderText("Encoding started");

}

調用job的now()方法以返回一個Promise值。

停止應用程序

使用@OnApplicationStop註釋可以在應用程序關閉時執行某些操作。

import play.jobs.*;

 

@OnApplicationStop

public class Bootstrap extends Job {

 

    public voiddoJob() {

       Fixture.deleteAll();

    }

}


發佈了8 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章