从 Spring 引导资源执行和处理 Void @Async 操作

Executing and handling Void @Async operations from Spring Boot resources

Java 8 和 Spring 在此处引导 2.x。我有一个 RESTful 资源,它将启动一个长 运行ning 操作,在某些情况下可能需要 15 - 20 分钟才能完成。我 认为 我想在服务层中利用 @Async 注释,但我愿意接受任何好的、优雅的 Spring 精通引导的解决方案!

迄今为止我最好的尝试:

@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);

    }

}

认为我很接近,但我正在努力:

谁能看出我哪里出错了?

  1. 删除对 CompletableFuture.get() 的调用。它等待未来完成。
  2. 将消费者传递给 thenAccept. You can find examples here
  3. 超时,在Java 9,查看orTimeOut. Check this for example. If you check the article in previous link, in Java 8, there is no clean way of handling timeouts. You can set default timeout for entire application by providing custom async executor. Check this Whosebug问题解决。