这里是 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(...)
(同样,大约 15 - 20 分钟后),但不能更快!;和 - 也许在异步操作上配置某种类型的超时,例如 30 分钟后失败并出现异常
有人能发现我哪里出了问题吗?
最佳答案
- 删除对 CompletableFuture.get() 的调用。它等待 future 完成。
- 将消费者传递至 thenAccept 。您可以找到示例here .
- 对于超时,在 Java 9 中,请检查 orTimeOut 。检查this例如。如果您查看前面链接中的文章,在 Java 8 中,没有干净的方法来处理超时。您可以通过提供自定义异步执行器来设置整个应用程序的默认超时。检查this stackoverflow 问题寻求解决方案。
关于java - 从 Spring Boot 资源执行和处理 Void @Async 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59851785/