I have a method that needs to return results immediately after it's called, even all the tasks in this method are not complete.
In this scenario:
Step 2 is what I am returning and step 3 is what I want to keep running in the background after I return to step 3.
I am not sure what direction to take to orchestrate these events. Below is my method, not sure exactly what to do about the addressRegistrationService.watchAndTransact(userAddresses);
task. It could take up to a full day to complete and the user needs the deposit address returned before it can deposit the funds.
@PostMapping("/registeraddress")
public ResponseEntity<Mono<UserAddressesDTO>> addUserAddress(@RequestBody UserAddresses userAddresses) throws Exception {
log.info("Registering {} with addresses {}", userAddresses.getAccountId(), userAddresses.getAddresses());
//Checking if we can use the user provided addresses and account id
if (addressRegistrationService.isRegistrationValid(userAddresses)) {
throw new InvalidAddressException("Address is invalid");
}
log.info("Deposit Address is {}", generateJobcoinAddress.generateJobcoinAddress());
//Generate the deposit address and add it the UserAddress
String depositAddress = generateJobcoinAddress.generateJobcoinAddress();
//Add input and deposit address to the object
UserAddressesDTO userAddressesDTO = new UserAddressesDTO(userAddresses.getAccountId(), depositAddress, userAddresses.getAddresses());
//Request the Jobcoin Service to start watching for the transaction
//Once Jobcoin Service detects it will post the transaction to the house account
//then to the user addresses - > we will be notified separately once this is complete
addressRegistrationService.watchAndTransact(userAddresses);
//Store addresses in database, calls the data-service to store these details
return ResponseEntity.ok().body(addressRegistrationService.saveAddressDB(userAddressesDTO));
}
You can use CompletableFuture
. So your code will look like...
CompletableFuture.runAsync(() -> addressRegistrationService.watchAndTransact(userAddresses));
It will run your watchAndTransact
method in a different thread. And main thread will not wait for result. So basically it will run on background.
Note: But incase of failure you will not know whats happened. So you can add some custom metrics & logs. This can be part of service it-self.
CompletableFuture.runAsync(() -> {
try {
addressRegistrationService.watchAndTransact(userAddresses);
// Notify user
} catch (RuntimeException e) {
// custom metrics implementation here
// log error here
}
});