I am trying to implement a generic solution for third party API(work in async way) but not getting any idea that how i can implement a call for rest of my application in synchronized way. Basically API is working like take request, process it and then give response when it finish but in meanwhile open to receive other requests as well. So i put API response method in a thread so that monitor continuously either there is a response or not by calling api response method with time interval.
API have interface to take request like:
public void api_execute(string UUID,String request);
API response object:
public APIReponse
{
private String UUID;
private String response_string
// Getter setter
}
I want to write a wrapper on top of this API in which have a single method so that different objects of my application use this to send request and receive response. so UUID will be create by this wrapper class but i am not getting that how i will wait a caller object until i received some response and also distinguish which caller send which request. I was thinking by using observer pattern here but seems to be not fit with this scenario. Can someone give me a hint how i can implement this.
You create async task executor using thread pool
ExecutorService threadpool = Executors.newFixedThreadPool(3);
public Future<APIReponse> submitTask(APIRequest request) throws InterruptedException, ExecutionException {
System.out.println("Submitting Task ...");
Future<APIReponse> future = threadpool.submit(new Callable<APIReponse>() {
#Override
public APIReponse call() throws Exception {
api_execute(request,UUID);
return new APIReponse();
}
});
return future;
Related
I have a Controller that must accept a request and do not wait for the finishing of the processing, give a response.
#PostMapping
#ResponseStatus(HttpStatus.CREATED)
public void processEvent(#RequestBody RequestMyObjectDTO requestMyObjectDTO) {
MyProcessor.process(requestMyObjectDTO);
}
After I give a response, I must execute the processing.
#Async
public void process(RequestMyObjectDTO myRequestObject) {
List<TestObject> testObjects= repository.findAllTestObject();
if (testObjects.isEmpty()) {
return;
}
.............
Is there any difference in where I will go to the database, in the asynchronous method, or outside it? In my case in Controller for example.
How it will impact behavior and what approaches are better?
Given that I need a check:
List<TestObject> testObjects= repository.findAllTestObject();
if (testObjects.isEmpty()) {
return;
}
At the same time, I expect that the controller may receive millions of requests.
i have a spring boot aplication and i want send email with javamail using ses on aws. but if I send an email, while it and sent no other process is executed.
I want to send the email through a thread, but I've implemented a thread in this way and even then the email sending process is not asynchronous.
when I make this request to send email and then list all to see how the processing is, as long as the sending of the email does not finish the list request is not executed
#GetMapping
public ResponseEntity<?> listarUsuarios(){
System.out.println("--------begin send mail------------");
new SendMail(emailService).run();
System.out.println("--------finish send mail------------");
List<Usuario> usuariosList = usuarioRepository.findAll(); // <- this process not is processed when send email not finish
return new ResponseEntity<>(usuariosList,HttpStatus.OK);
}
.
public class SendMail extends Thread {
public EmailService emailService;
public SendMail(EmailService emailService) {
this.emailService = emailService;
}
public void run(){
try {
emailService.EnviarEmailDeConfirmacao("daviresio#gmail.com", 1, "Subject test mail","body test mail");
} catch (Exception e) {
e.printStackTrace();
}
}
}
You are not starting a new thread. Instead, you are calling the run() method directly:
new SendMail(emailService).run();
Call start() instead to start a new thread:
new SendMail(emailService).start();
By the way, starting new threads like this from a web application is bad practice. It's better to use for example an ExecutorService to manage the threads that send e-mails, so that you don't get a potentially unlimited number of threads when many users are calling this functionality at the same time.
You should use the start() method to spawn as a new thread. If you call run() directly it is run in the same thread. See https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html
Use start() instead of run().
Run will execute it on the existing thread.
Start will execute it on a new thread.
So change your code to the following if you want it to execute asynchronous:
new SendMail(emailService).start();
new SendMail(emailService).start(); - will start a new Thread and will execute SendMail.run(); in the new Thread.
new SendMail(emailService).run(); - is just a method call which executed in the same thread.
I'm looking for a best practice for making concurrent network requests using the OKHTTP library.
Basically here's what I want to do:
I want to write a method that makes N concurrent network requests to different URLs, and return ONLY when ALL N requests have returned.
I thought about manually writing Threads and Runnables and such to create a group of request pool, but was wondering if there's some sort of easier way to do this. So my question is:
Does OKHTTP support concurrent request API natively somehow?
If not, what's the best way to implement this?
OkHttp natively supports asynchronous requests efficiently e.g. sharing the optimum number of connections.
See https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/AsynchronousGet.java
For the second part of the question, you use a CountdownLatch or you can bridge to java Futures like the following
public class OkHttpResponseFuture implements Callback {
public final CompletableFuture<Response> future = new CompletableFuture<>();
public OkHttpResponseFuture() {
}
#Override public void onFailure(Call call, IOException e) {
future.completeExceptionally(e);
}
#Override public void onResponse(Call call, Response response) throws IOException {
future.complete(response);
}
}
And call
private Future<Response> makeRequest(OkHttpClient client, Request request) {
Call call = client.newCall(request);
OkHttpResponseFuture result = new OkHttpResponseFuture();
call.enqueue(result);
return result.future;
}
At that point you can use methods like CompletableFuture.allOf
n.b. if you wrap with Futures, it can be easy to not close the Response objects when one fails.
In Java, is there any way to call and handle asynchronous method inside a thread?
Consider an scenario in which one of the method inside thread body takes more time to execute it. Because of that, thread completion takes more time.
I have tried some examples by using concurrency package classes like FutureTask and Executors.
Is it possible to implement and handle all exceptions inside asynchronous method? and Is it possible to get success or error responses like AJAX success and error handlers in JavaScript?
How will we ensure that asynchronous method successfully executed or not (with or without parent thread context)?
Most natural way of communication between async method and parent thread is standard class CompletableFuture:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class AsyncExample {
String input; // common data
// async method
public String toLower() {
return input.toLowerCase();
}
// method on main thread
public void run() {
input = "INPUT"; // set common data
try {
// start async method
CompletableFuture<String> future = CompletableFuture.supplyAsync(this::toLower);
// here we can work in parallel
String result = future.get(); // get the async result
System.out.println("input="+input+"; result="+result);
} catch (InterruptedException | ExecutionException e) {
}
}
public static void main(String[] args) {
new AsyncExample().run();
}
}
Note that creation and warming of an Executor, including the default executor used in the example, requires some time (50 ms on my computer), so you may want to create and warm one beforehand, e.g. by supplying an empty method:
CompletableFuture.supplyAsync(()->null).get();
I have a small Spring Boot app waiting for REST calls to start an async job. However what I'd like to do next is get results of those async jobs and store them in DB. But I don't know how to use object returned with Future asynchronically.
Here is more or less what I have:
#RequestMapping("/vlan/{id}/{name}")
public void performVLANConfig(#PathVariable("id") int id, #PathVariable("name") String name) {
logger.debug("Received req");
Future<ProcessedRequest> processedRequestFuture= asyncService.processVlan(id, name);
processedRequestRepository.save(processedRequest);
}
But now it just waits for async call to end. Is there any way to let the async method live its life and after it has completed store this completition error?
You need to attach a callback. If you using Future then you can't attach a callback to it, assign to a ListenableFuture instead, the service needs to return a ListenableFuture of course.
ListenableFuture<ProcessedRequest> future = asyncService.processVlan(id, name);
future.addCallback(new ListenableFutureCallback<ProcessedRequest>() {
#Override
public void onFailure(Throwable throwable) {
// deal with it
}
#Override
public void onSuccess(ProcessedRequest processedRequest) {
processedRequestRepository.save(processedRequest);
}
});