java - 从 Spring Boot 资源执行和处理 Void @Async 操作

标签 java spring-boot spring-async

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

有人能发现我哪里出了问题吗?

最佳答案

  1. 删除对 CompletableFuture.get() 的调用。它等待 future 完成。
  2. 将消费者传递至 thenAccept 。您可以找到示例here .
  3. 对于超时,在 Java 9 中,请检查 orTimeOut 。检查this例如。如果您查看前面链接中的文章,在 Java 8 中,没有干净的方法来处理超时。您可以通过提供自定义异步执行器来设置整个应用程序的默认超时。检查this stackoverflow 问题寻求解决方案。

关于java - 从 Spring Boot 资源执行和处理 Void @Async 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59851785/

相关文章:

java - JJWT/Jackson 改变了使用的 ObjectMapper

java - 如何从电子邮件中获取内联图像?

java - Spark : driver/worker configuration. 驱动程序是否在主节点上运行?

java - 在 JPanel 中加载图像?

java - 带有 Spring Boot 和 Spring Data Neo4j 的 REST API

java - @Async with CompletableFuture#get 不会抛出自定义 RuntimeException

spring-boot - Spring Web Flux 和 Spring Async 方法有什么区别?

java - 从存储库返回实体时如何使用 CompletableFuture.thenCompose() ?

java - Spring Boot 应用程序如何在内部工作?

java - 将 SpEL 输出转换为 long 以用作注释参数