【发布时间】:2020-05-08 03:28:31
【问题描述】:
Java 8 和 Spring Boot 2.x 在这里。我有一个 RESTful 资源,它将启动一个长时间运行的操作,在某些情况下可能需要 15 到 20 分钟才能完成。我认为我想在服务层中利用 @Async 注释,但我愿意接受任何好的、优雅的 Spring Boot-savvy 解决方案!
迄今为止我最好的尝试:
@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 分钟后失败并出现异常
谁能看出我哪里出错了?
【问题讨论】:
标签: java spring-boot spring-async