Java Dropwizard中的JAX-RS:处理具有即时响应的异步调用
我有一个ResourceJava Dropwizard中的JAX-RS:处理具有即时响应的异步调用,java,jersey-2.0,dropwizard,Java,Jersey 2.0,Dropwizard,我有一个Resource类,它有一个@ManagedAsync方法类,如下所示: @Path("my-resource") public class MyResource extends BaseResource{ private DatumDAO datumDAO; public MyResource(DatumDAO datumDAO){ this.datumDAO = datumDAO; } public void cleanDatum
类
,它有一个@ManagedAsync
方法类,如下所示:
@Path("my-resource")
public class MyResource extends BaseResource{
private DatumDAO datumDAO;
public MyResource(DatumDAO datumDAO){
this.datumDAO = datumDAO;
}
public void cleanDatum(Datum datum){
//time taking operations
}
@GET
@ManagedAsync
@Path("/cleanup/{from}/{till}/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@UnitOfWork
public void cleanupDirtyData(@Suspended final AsyncResponse asyncResponse, @PathParam("from") DateTimeParam from,
@PathParam("till") DateTimeParam till) throws IOException{
logger.debug("will try to cleanup dirty data in range: " + from + " " + till);
List<Datum> data = datumDAO.getALlDirtyDatumInRange(from.get().toDate(), till.get().toDate());
Map<Long,String> cleanupMap = new HashMap<Long,String>();
for(Datum datum: data){
cleanDatum(datum);
cleanupMap.put(datum.getId(), "cleaned");
}
// this response need to be sent [can be ignored]
asyncResponse.resume(Response.status(HttpStatus.OK_200).entity(cleanupMap).build());
}
}
@Path("my-resource")
public class MyResource extends BaseResource{
private DatumDAO datumDAO;
public MyResource(DatumDAO datumDAO){
this.datumDAO = datumDAO;
}
public void cleanDatum(Datum datum){
//time taking operations
}
@GET
@ManagedAsync
@Path("/cleanup/{from}/{till}/")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@UnitOfWork
public void cleanupDirtyData(@Suspended final AsyncResponse asyncResponse, @PathParam("from") DateTimeParam from,
@PathParam("till") DateTimeParam till) throws IOException{
// Register handler and set timeout
asyncResponse.setTimeoutHandler(new TimeoutHandler() {
public void handleTimeout(AsyncResponse ar) {
asyncResponse.resume(Response.status(SERVICE_UNAVAILABLE).entity(
"Operation timed out -- please try again").build());
}
});
ar.setTimeout(15, TimeUnit.SECONDS);
logger.debug("will try to cleanup dirty data in range: " + from + " " + till);
List<Datum> data = datumDAO.getALlDirtyDatumInRange(from.get().toDate(), till.get().toDate());
Map<Long,String> cleanupMap = new HashMap<Long,String>();
for(Datum datum: data){
cleanDatum(datum);
cleanupMap.put(datum.getId(), "cleaned");
}
// this response need to be sent [can be ignored]
asyncResponse.resume(Response.status(HttpStatus.OK_200).entity(cleanupMap).build());
}
}
JAX-RS异步服务器API是关于容器如何管理请求的。但它仍然会保留请求,不会影响客户体验
引用泽西岛文件中关于:
注意,使用服务器端异步处理模型将
不会提高客户端感知到的请求处理时间。信息技术
但是,通过释放
初始请求处理线程返回到I/O容器,而
请求可能仍在队列中等待处理,或者
处理可能仍在另一个专用线程上运行。这个
发布的I/O容器线程可用于接受和处理新的
传入请求连接
如果你想给客户一个即时的回应,你可能会寻找类似的东西:
@Singleton
@路径(“昂贵任务”)
公共类费用来源{
私人遗嘱执行人;
私人未来结果;
@施工后
public void onCreate(){
this.executor=Executors.newSingleThreadExecutor();
}
@职位
公众回应startTask(){
futureResult=executor.submit(new ExpensiveTask());
返回Response.status(status.ACCEPTED.build();
}
@得到
公共响应getResult()引发ExecutionException、InterruptedException{
if(futuresult!=null&&futuresult.isDone()){
返回Response.status(status.OK).entity(futuresult.get()).build();
}否则{
返回Response.status(status.forbidded).entity(“稍后重试”).build();
}
}
@发情前期
公共空间{
此为.executor.shutdownow();
}
}
公共类ExpensiveTask实现可调用{
@凌驾
公共字符串调用()引发异常{
试一试{
睡眠(10000);
}捕捉(中断异常e){
e、 printStackTrace();
}
返回“任务完成”;
}
}
在servlet容器中,您可以使用来运行昂贵的任务。在java EE容器中,你应该考虑一个.< /p>“既然调用CurruffDigTeDATA需要一段时间,我不希望客户端完全等待它”——你想知道为什么没有意义吗?因为在代码中,您将向客户端返回一个响应主体。如果响应主体是“长时间运行的执行”的一部分,那么当获取主体的执行没有完成时,您希望如何将响应返回给客户机?如果我错了,您的代码中长时间运行的任务到底是什么?@peeskillet这是一个占位符代码,我不需要在任务完成后返回任何响应。长时间运行的任务涉及大量磁盘I/O,最多需要15分钟。很好的解释+1。