`
desert3
  • 浏览: 2139600 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

Play framework 1.2.3 Jobs定时任务、异步任务、引导任务、触发任务、关闭任务

 
阅读更多
Play framework是一个web应用程序,大部分的应用逻辑都是通过在Controllers中以响应HTTP请求的方式来完成的。

有时候你可能需要执行一些和HTTP请求无关的应用逻辑。这在处理一些初始化任务、维护任务、不阻塞HTTP请求连接池的耗时任务时非常有用。

Jobs是完全受Framework管理的。也就是说play框架会为你管理所有数据库连接事宜、JPA entity manager同步、事物管理

要创建一个Job,只需要简单地继承play.jobs.Job类就可以。
package jobs;
 
import play.jobs.*;
 
public class MyJob extends Job {
    
    public void doJob() {
        // execute some application logic here ...
    }
    

}
如果Job需要返回值的话,那么覆盖doJobWithResult()方法即可。
package jobs;
 
import play.jobs.*;
  
public class MyJob extends Job<String> {
    
    public String doJobWithResult() {
        // execute some application logic here ...
        return result;
    }
    
}

这里的String只是一个例子,你可以用任何其他类型。

引导Job(Bootstrap job):
Bootstrap jobs是在play应用程序启动的时候被执行(注意DEV、PROD模式的区别)。通过@OnApplicationStart注解就可以把一个job标记为bootstrap job。
import play.jobs.*;
 
@OnApplicationStart
public class Bootstrap extends Job {
    
    public void doJob() {
        if(Page.count() == 0) {
            new Page("root").save();
            Logger.info("The page tree was empty. A root page has been created.");
        }
    }
    
}

对于Bootstrap jobs不需要返回值,即使你做了,返回值也会丢失
默认情况下,所有被@OnApplicationStart注解标记的job按顺序执行完成后,应用程序才开始处理进来的HTTP请求
如果你想要在应用程序启动时就开始一个job,同时,你想不等这个job执行完就直接开始处理进来的HTTP请求,你可以如下这样通过给注解增加async=true这个参数来达到要求的效果:@OnApplicationStart(async=true)。
所有@OnApplicationStart(async=true)标记的job在应用程序启动时会自动启动,并且所有这些异步job是在同一时刻启动的

定时任务:
定时任务就是play框架根据用户的设置周期性地执行任务。使用@Every注解来标记job每隔多久执行一次。
import play.jobs.*;
 
@Every("1h")
public class Bootstrap extends Job {
    
    public void doJob() {
        List<User> newUsers = User.find("newAccount = true").fetch();
        for(User user : newUsers) {
            Notifier.sayWelcome(user);
        }
    }
    
}

如果@Every不够用的话,也可以使用更加灵活的@On注解来设置定时任务的时间间隔@On的设置采用的是CRON表达式
import play.jobs.*;
 
/** Fire at 12pm (noon) every day **/ 
@On("0 0 12 * * ?")
public class Bootstrap extends Job {
    
    public void doJob() {
        Logger.info("Maintenance job ...");
        ...
    }
    
}

定时任务时,也不需要返回值,即使你做了,返回值也会丢失

触发task jobs:
在任何时候,你都可以通过调用job实例的now()方法来触发job来执行一个特殊的任务。然后这个job就会以非阻塞的方式被立即执行
public static void encodeVideo(Long videoId) {
    new VideoEncoder(videoId).now();
    renderText("Encoding started");
}

在job实例上调用now()方法,将会返回一个Promise约定的值。当job完成后,你可以用Promise来接收job的执行结果。看怎么做的??

应用程序关闭时执行的任务:
可以通过@OnApplicationStop注解来声明在应用程序关闭时要执行的job。
import play.jobs.*;
@OnApplicationStop
public class Bootstrap extends Job {
public void doJob() { Fixture.deleteAll(); }
}

参考:Asynchronous Jobs
分享到:
评论
2 楼 feihangchen 2016-08-01  
@OnApplicationStop 
public class Bootstrap extends Job { 
public void doJob() {  } 
}

以上代码如何停止所有的定时器。有时需要重启应用服务,希望在重启之前先让所有定时器停止工作。
1 楼 hw04551 2013-08-01  
楼主你好
我也用playframwork,在应用中我启动了好几个Job去执行对应的数据解析,现在遇到一个问题,这个几个Job执行一段时间后,其中一个或这个几个会停止工作,日志中也没有任何的异常信息出现。好像Job在执行过程中阻塞了一样,Job都是3秒执行一次。请问该怎么解决Job停止工作的现象。

相关推荐

Global site tag (gtag.js) - Google Analytics