我有一个奇怪的问题。
状态是EndpointStatus的类级别实例(构造函数中未提供工作)
private EndpointStatus status = new EndpointStatus(1L, EndpointStatus.Status.AVAILABLE);
....omitted....
@POST
@Path("/calculated")
public Response reCalculated(String req,
final @Context SecurityContext securityContext) {
if ( status.isBusy() ) { return Response.ok( status.getCurrentJob() ).build(); }
String uuid = UUID.randomUUID().toString();
status.setStatus(EndpointStatus.Status.BUSY);
CurrentJob job = new CurrentJob();
job.setId(1L);
job.setJobStatus("ACTIVE");
job.setJobId(uuid);
status.setCurrentJob(job);
executorService.execute(() -> {
try {
thymeNewDateRange.getDataForDateRange(thymeDate, null, status);
status.setCurrentJob(null);
} catch (Exception e) {
serverLogger.error(e);
}
});
return Response.accepted(job).build();
}
所以我在这里收到POST
从初始职位返回:(职位类别)
{
"id" : 1,
"jobId" : "5d974c2d-e01a-4842-ad5f-1ef7d78901c0",
"jobStatus" : "ACTIVE",
}
这里的一切都很好。客户端已经开始查询5d974c2d-e01a-4842-ad5f-1ef7d78901c0作为url,只要结果还没有准备好,它就会返回相同的JSON。
但是但是
在前几次查询后不久(在此SO帖子之前,客户端运行了3个查询,在此之前是5个,所以是随机的)
status.setCurrentJob(null);
似乎会被调用(在POST方法中长时间运行的工作之下) 即使作业刚刚开始,这也将使端点从繁忙返回到可用状态。
设置为空后,作业端点将响应:(由于currentJob设置为null,所以返回了状态类)
{
"id" : 1,
"status" : "AVAILABLE",
"currentJob" : null,
"busy" : false
}
这又将停止从客户端查询,因此客户端将丢失所有数据。
不应该
status.setCurrentJob(null);
在
之后被调用thymeNewDateRange.getDataForDateRange(thymeDate, null, status);
完成了吗?在整个应用程序中,这是将job设置为null的唯一实例,因此应该从此处传播?
用于查询工作的端点
@GET
@Path("/job")
public Response queryJob(@Context SecurityContext securityContext,
@QueryParam("pid") String pid) {
if( status.getCurrentJob() != null ) {
return Response.ok(status.getCurrentJob()).build();
}
if( status.getStatus() == EndpointStatus.Status.AVAILABLE ) {
//JOB HAS ENDED - but this will still trigger too early
return Response.ok(status).build();
}else {
return Response.ok("ERROR STATE").build();
}
}
请随时问我忘记提及的任何问题。.这是一篇冗长而复杂的帖子。
干杯;)
编辑,我需要帮助或驱魔人...
尝试使用volatile(谢谢@paulturnip),但没有帮助
此外,该问题似乎仅在“真实”测试服务器上仍然存在。 当使用localhost:8080在本地运行时,此问题永远不会出现...
但是在服务器上运行时,这种情况一直在发生。
我将logger作为@Path(“ / job”)的第一行添加到日志:
serverLogger.info("STATUS: " + status.getStatus().toString() + " JOB STATUS: " + status.getCurrentJob().getJobStatus() );
在本地,再次没有nullPointer。但是只要在适当的服务器环境上运行,status.getCurrentJob().getJobStatus()
就会以某种方式抛出NullPointerException,甚至是
CurrentJob job = new CurrentJob();
job.setId(1L);
job.setJobStatus("ACTIVE");
job.setJobId(uuid);
status.setCurrentJob(job);
已设置,字面上是(/ calculated)之前的一个呼叫
EDIT2:
CurrentJob bean:
@Entity
public class CurrentJob {
@Id
private Long id;
private volatile String jobId;
private volatile String jobStatus;
.... basic getter&setter&constructor ....
我正在使用休眠模式,所以使用@Entity和@Id,但是由于我不打算保存该实例,我想知道它们是否可能会干扰状态?