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 分钟后失败并出现异常
谁能发现我哪里出错了?