0

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 分钟后失败并出现异常

谁能发现我哪里出错了?

4

1 回答 1

2
  1. 删除对CompletableFuture.get()的调用。它等待未来完成。
  2. 将消费者传递给thenAccept您可以在此处找到示例。
  3. 对于超时,在 Java 9 中,检查orTimeOut。例如检查这个。如果您查看上一个链接中的文章,在 Java 8 中,没有处理超时的干净方法。您可以通过提供自定义异步执行器为整个应用程序设置默认超时。检查这个stackoverflow问题以获得解决方案。
于 2020-01-22T04:22:39.907 回答