Разрешить методу Spring REST вызывать асинхронный метод и не ждать ответа - PullRequest
0 голосов
/ 27 февраля 2020

Допустим, у меня есть метод foo(), который выполняется примерно на 30 минут каждый день в 3 часа ночи.

1003 * В традиционном смысле мы могли бы использовать Spring Scheduler и аннотацию cron :
@Scheduled(cron = "0 0 3 ? * *")
public void foo() {
    ...
}

К сожалению, это решение для меня недоступно из-за резервирования руководящего проекта при использовании Spring Scheduler над инструментом корпоративного планирования.

В данном случае мы имеем инструмент планирования, работающий с конечной точкой REST следующего метода:

@RequestMapping(value = "/foo", method = RequestMethod.Post)
public ResponseEntity<Boolean> doFoo() {
    foo(); //goal is to make this not hold up the return statement

    return ResponseEntity.ok(true);
}

Есть ли способ заставить foo выполняться асинхронно, не ожидая завершения в будущем? foo() должен продолжаться сам по себе столько времени, сколько ему нужно, и реакция скручивания должна быть почти немедленной.

1 Ответ

1 голос
/ 27 февраля 2020

Есть ли способ заставить foo() выполняться асинхронно, не ожидая завершения в будущем?

Вы можете определить метод foo() в Spring Bean. Поскольку вас не интересует любое возвращаемое значение, вы можете использовать void в качестве типа возвращаемого значения. Затем аннотируйте foo() с помощью @Async:

@Service
public class FooService {

    @Async
    public void foo() {
        ...
    }
}

Также необходимо убедиться, что у вас есть @EnableAsync в классе конфигурации:

@EnableAsync
@Configuration
public class AsyncConfig {

}

Затем вы можете вызвать foo() из метода контроллера:

@RequiredArgsConstructor
@RequestMapping(value = "/foo")
public class FooController {

    private final FooService fooService;

    @PostMapping
    public ResponseEntity<Boolean> doFoo() {
        fooService.foo();
        return ResponseEntity.ok(true);
    }
}

И, в случае необходимости, вы также можете вызвать foo() из @Scheduled -аннотированного метода:

@Scheduled(cron = "0 0 3 ? * *")
public void foo() {
    fooService.foo();
}

Позвольте мне подчеркнуть, что 202 будет более точным кодом состояния, чем 200 для этой ситуации:

6.3.3. 202 Принят

Код состояния 202 (Принят) указывает, что запрос был принят для обработки, но обработка не была завершена. Запрос может или не может быть в конечном итоге обработан, так как он может быть отклонен, когда обработка действительно имеет место. В HTTP нет возможности повторно отправить код состояния из асинхронной операции.

Ответ 202 намеренно не является обязательным. Его цель - позволить серверу принять запрос для какого-либо другого процесса (возможно, пакетно-ориентированного процесса, который выполняется только один раз в день), не требуя, чтобы соединение пользовательского агента с сервером сохранялось до завершения процесса. Представление, отправленное с этим ответом, должно описать текущее состояние запроса и указать (или встроить) монитор состояния, который может предоставить пользователю оценку того, когда запрос будет выполнен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...