英文:
Make an Asynch call that needs to store ids to database without blocking
问题
我正在使用Spring的@Asynch注解。我有一个场景,需要进行两个API调用。其中一个API调用通过@Async打开了一个新线程,因为调用方不关心这个API调用,只关心第一个API调用。然而,这两个API调用都会返回我想要存储到数据库中的ID。我该如何完成这个任务?由于数据库的存储依赖于这两个ID,它将阻止我打开新线程的意图。
public class SecondAPICallService {
    @Async
    public CompletableFuture<String> makeSecondApiCall(String firstAPICallId) {
        var secondAPICallId = webClient.post(firstAPICallId, ...);
        return CompletableFuture.completedFuture(secondAPICallId);
    }
}
public class FirstAPICallService {
    @Autowired
    SecondAPICallService secondAPICallService;
    @Autowired
    DatabaseService dbService;
    public Response makeApiCall(String firstAPICallId) {
        Response response = webClient.post(..);
        String id = response.getId();
        CompletableFuture<String> secondAPICallId = secondAPICallService.makeSecondApiCall(id);
        // 这里使用.get()会阻塞线程,但我不确定该怎么办,因为我需要存储到数据库中
        String secondId = secondAPICallId.get();
        dbService.save(id, secondId);
        return response;
    }
}
@Configuration
@EnableAsync
public class AsyncConfiguration {
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(3);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("AsyncThread-");
        executor.initialize();
        return executor;
    }
}
希望这对你有帮助。
英文:
I am using Spring @Asynch. I have a scenrio where I have to make two API calls. One API call opens a new thread via @Async since the caller doesn't care about this API call and only cares about the first API call. However, both these API calls return back ids that I want to store into the database. How will I go about accomplishing this? Since the storing of the database depends on both the ids it will block my intent of opening a new thread.
public class SecondAPICallService {
    @Asynch
    public CompletableFuture<String> makeSecondApiCall(String firstAPICallId) {
	   var secondAPICallId = webClient.post(firstAPICallId, ...);
	   return  CompletableFuture.completedFuture(secondAPICallId);
    }
}
public class FirstAPICallService {
    @Autowire
    SecondAPICallService secondAPICallService;
    @Autowire
    DatabaseService dbService;	
    public Response makeApiCall(String firstAPICallId) {
	   Response response = webClient.post(..);
	   String id = response.getId();
	   CompletableFuture<String> secondAPICallId = secondAPICallService.makeSecondApiCall(id);
	   // This here blocks my thread with .get but not sure what to do since I need to store in db
       String secondId = secondAPICallId.get();
	   dbService.save(id, secondId);		
	   return response;
   }
}
@Configuration
@EnableAsync
public class AsyncConfiguration {
    @Bean(name = "asyncExecutor")
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(3);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("AsynchThread-");
        executor.initialize();
        return executor;
    }
}
答案1
得分: 1
public class SecondAPICallService {
    @Async
    public CompletableFuture<String> makeSecondApiCall(String firstAPICallId) {
        // 进行第二次API调用
        CompletableFuture<String> future = new CompletableFuture<>();
        // 异步执行第二次API调用
        // 一旦获取到第二次API调用的ID,使用该ID来完成CompletableFuture
        // 例如:
        String secondId = // 获取第二次API调用的ID
        future.complete(secondId);
        return future;
    }
}
public class FirstAPICallService {
    @Autowired
    SecondAPICallService secondAPICallService;
    @Autowired
    DatabaseService dbService;  
    public Response makeApiCall(String firstAPICallId) {
        Response response = webClient.post(..);
        String id = response.getId();
        
        // 异步执行第二次API调用
        CompletableFuture<String> secondAPICallId = secondAPICallService.makeSecondApiCall(id);
        
        // 注册一个回调函数,以在第二次API调用完成时执行
        secondAPICallId.thenAcceptAsync(secondId -> {
            // 将ID保存到数据库
            dbService.save(id, secondId);
        });
        
        return response;
    }
}
英文:
 @Async
 public CompletableFuture<String> makeSecondApiCall(String firstAPICallId) {
     // Make the second API call
     CompletableFuture<String> future = new CompletableFuture<>();
     // Perform the second API call asynchronously
     // Once you obtain the second API call ID, complete the CompletableFuture
     // with the second API call ID value
     // For example:
     String secondId = // Obtain the second API call ID
     future.complete(secondId);
     return future;
 }
}
public class FirstAPICallService {
 @Autowired
 SecondAPICallService secondAPICallService;
 @Autowired
 DatabaseService dbService;  
 public Response makeApiCall(String firstAPICallId) {
     Response response = webClient.post(..);
     String id = response.getId();
     
     // Perform the second API call asynchronously
     CompletableFuture<String> secondAPICallId = secondAPICallService.makeSecondApiCall(id);
     
     // Register a callback function to be executed when the second API call completes
     secondAPICallId.thenAcceptAsync(secondId -> {
         // Save the IDs to the database
         dbService.save(id, secondId);
     });
     
     return response;
 }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论