Выполнение и обработка операций Void @ Asyn c из ресурсов Spring Boot - PullRequest
0 голосов
/ 22 января 2020

Java 8 и Spring Boot 2.x здесь. У меня есть ресурс RESTful, который запускает длительную операцию, которая в некоторых случаях может занять 15-20 минут. Я думаю Я хочу использовать аннотацию @Async здесь, на служебном уровне, но я открыт для любого хорошего, элегантного решения, подходящего для Spring Boot!

Моя лучшая попытка далеко:

@RestController
@RequestMapping(path = "/v1/fizzbuzzes")
public class FizzbuzzResource {

    @Autowired
    private FizzbuzzService fizzbuzzService;

    @Autowired
    private FizzbuzzRepository fizzbuzzRepository;

    @Autowired
    @Qualifier("fizzbuzz.ids")
    private List<String> fizzbuzzList;

    @PostMapping("/{fizzbuzzId}")
    public ResponseEntity<Void> runFizzbuzzOperations(@PathVariable String fizzbuzzId)
            throws ExecutionException, InterruptedException {

        ResponseEntity responseEntity;

        // verify the fizzbuzzId is valid -- if it is, we process it
        Optional<Fizzbuzz> fbOpt = fizzbuzzRepository.lookupMorph(fizzbuzzId);
        if (fbOpt.isPresent()) {

            fizzbuzzList.add(fizzbuzzId);

            CompletableFuture<Void> future = fizzbuzzService.runAsync(fbOpt.get());
            future.get();
            // TODO: need help here

            // TODO: decrement the list once the async has completed -- ONLY do once async has finished
            fizzbuzzList.remove(fizzbuzzId);

            // return success immediately (dont wait for the async processing)
            responseEntity = ResponseEntity.ok().build();

        } else {
            responseEntity = ResponseEntity.notFound().build();
        }

        return responseEntity;

    }

}

@Service
public class FizzbuzzService {

    @Async
    public CompletableFuture<Void> runAsync(Fizzbuzz fizzbuzz) {

        // do something that can take 15 - 20 mins to complete
        // it actually is writing a massive amount of data to the file system
        // so there's nothing to really "return" so we just return null (?)

        return CompletableFuture.completedFuture(null);

    }

}

Я думаю Я близок, но я борюсь с:

  • Как правильно вызвать fizzbuzzService.runAsync(...) таким образом, что он фактически работает асинхронно, и поэтому ResponseEntity.ok().build() под ним запускается немедленно, вместо того, чтобы ждать ~ 15 минут, как в противном случае; и
  • Как запустить fizzbuzzList.remove(...), как только завершится метод обслуживания asyn c (опять-таки, через 15-20 минут), но не раньше !; и
  • Возможно настроить некоторый тип тайм-аута для асинхронной операции c, с ошибкой, скажем, через 30 минут

Может кто-нибудь, где я иду не так?

1 Ответ

2 голосов
/ 22 января 2020
  1. Удалить вызов CompletableFuture.get () . Это ждет будущего, чтобы закончить.
  2. Передать потребителю затем принять . Вы можете найти примеры здесь .
  3. Для тайм-аутов, в Java 9, проверьте orTimeOut . Проверьте это например. Если вы проверите статью в предыдущей ссылке, в Java 8, нет чистого способа обработки таймаутов. Вы можете установить время ожидания по умолчанию для всего приложения, предоставив пользовательский asyn c executor. Проверьте этот stackoverflow вопрос для решения.
...