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 минут
Может кто-нибудь, где я иду не так?