进行一个异步调用,需要将ID存储到数据库而不阻塞。

huangapple go评论70阅读模式
英文:

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&lt;String&gt; 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&lt;String&gt; 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 = &quot;asyncExecutor&quot;)
    public Executor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(3);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix(&quot;AsynchThread-&quot;);
        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&lt;String&gt; makeSecondApiCall(String firstAPICallId) {
     // Make the second API call
     CompletableFuture&lt;String&gt; future = new CompletableFuture&lt;&gt;();
     // 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&lt;String&gt; secondAPICallId = secondAPICallService.makeSecondApiCall(id);
     
     // Register a callback function to be executed when the second API call completes
     secondAPICallId.thenAcceptAsync(secondId -&gt; {
         // Save the IDs to the database
         dbService.save(id, secondId);
     });
     
     return response;
 }
}

huangapple
  • 本文由 发表于 2023年7月13日 21:53:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76680173.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定