Весна случайно теряет боб? - PullRequest
3 голосов
/ 24 апреля 2019

У меня странная проблема.

Статус - это экземпляр класса класса 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

  1. изменения статуса с AVAILABLE -> BUSY
  2. создание объекта задания с сгенерированным UUID.
  3. Затем объект задания устанавливается в статус объекта.
  4. немедленно верните 202 с UUID (Долгосрочное задание)

Возврат с начального поста: (класс заданий)

{
"id" : 1,
"jobId" : "5d974c2d-e01a-4842-ad5f-1ef7d78901c0",
"jobStatus" : "ACTIVE",
}

здесь все в порядке.Клиент начал запрашивать 5d974c2d-e01a-4842-ad5f-1ef7d78901c0 в качестве URL-адреса и получает тот же JSON обратно, пока результаты не готовы.

, но вскоре после этого

первые несколько запросов (до этого SO сообщения, клиент выполнял 3 запроса, до этого он был 5, поэтому случайный)

status.setCurrentJob(null);

, по-видимому, будет вызвано (ниже долгосрочного задания в методе POST). Это вернетконечная точка от BUSY до AVAILABLE, даже если задание только началось и для его завершения потребуются часы.

После установки нулевого задания конечная точка ответит: (класс состояния, возвращенный, поскольку currentJob имеет значение null)

{
"id" : 1,
"status" : "AVAILABLE",
"currentJob" : null,
"busy" : false
 }

, который, в свою очередь, прекратит запрашивать у клиента, поэтому клиент потеряет все данные ..

Не следует

 status.setCurrentJob(null);

вызывать сразу после

thymeNewDateRange.getDataForDateRange(thymeDate, null, status);

завершено?Это единственный случай установки задания на 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();
    }


}

Пожалуйста, не стесняйтесь спрашивать все, что я забылупомянуть ... это довольно длинный и сложный пост.

Cheers;)

EDIT ооооо, мне нужна помощь или экзорцист ...

пробовал с volatile (спасибо @paulturnip), но это не помогло

, кроме того проблема, похоже, сохраняется только на "реальном" тестовом сервере.При локальном запуске с localhost: 8080 эта проблема никогда не возникает ...

, но при запуске на сервере это просто происходит.

я добавил регистратор в качестве первой строки в @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);

установлено, буквально за один вызов до (/ рассчитано)

EDIT2:

Боб CurrentJob:

@Entity
public class CurrentJob {

@Id
private Long id;
private volatile String jobId;
private volatile String jobStatus;

.... basic getter&setter&constructor ....

Я использую hibernate, так что @Entity и @Id, но я не планировал сохранять этот экземпляр, мне было интересно, если ониможет как-то мешать государству?

...