Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to check time being taken by a method call in parallel

In a Spring Boot service class, let's say that I am making a method call processEvent().
The method processEvent() might be doing N number of things including making REST calls to other services.

How to check the time being taken by the method in parallel and if it crosses the threshold, then do something else e.g. throw exception ?

class EventService {  

    public void processEvent(ServiceContext context, Event event) {     

      // Field a time checker here for the below method.  
      processEvent(event);  
    }  
    public void processEvent(Event event) {  
      // this method does many things.  
    }  
}

Can this be achieved using CompletionService ? If yes, Please give an example!

EDIT:
The following code works but I have one query:

public void processEvent(ServiceContext context, Event event) {  

LOGGER.debug("Timestamp before submitting task = {}", System.currentTimeMillis());  

  Future<EventResponse> future = executor.submit(() -> {  
    LOGGER.debug("Timestamp before invoking = {}", System.currentTimeMillis());
    EventResponse eventResponse = processEvent(event);  
    LOGGER.debug("Timestamp after invoking = {}", System.currentTimeMillis());  
    return eventResponse;  
  });  

  try {
    LOGGER.debug("Thread sleep starts at = {}", System.currentTimeMillis());
    Thread.sleep(5000);
    LOGGER.debug("Thread sleep ended at = {}", System.currentTimeMillis());
  } catch (InterruptedException e) {
    LOGGER.debug("Going to print stack trace....");
    e.printStackTrace();
  }  

  if (!future.isDone()) {
    future.cancel(true);
    LOGGER.debug("task executor cancelled at = {}", System.currentTimeMillis());
  } else {
    EventResponse response = future.get();
    LOGGER.debug("Received Event ID = {}", response.getEventDetailsList().get(0).getEventID());
    return response;
  }  

  LOGGER.debug("Going to return error response at = {}", System.currentTimeMillis());  
  throw new Exception("Message");  
}

I am getting the below logs:

Timestamp before submitting task = 1579005638324
Thread sleep starts at = 1579005638326
Timestamp before invoking = 1579005638326
Thread sleep ended at = 1579005638526
task executor cancelled at = 1579005638527
Going to return error response at = 1579005638527
Timestamp after invoking = 1579005645228

How "Timestamp after invoking" is logged after "task executor cancelled at" ?

like image 206
mukund Avatar asked Jan 18 '26 11:01

mukund


1 Answers

You can use ThreadPoolTaskExecutor to submit the task, then sleep for a certain amount of time, then check if the task is completed and interrupt it, if it's still working. However, you can't just kill the task, you'll have to periodically check for the interrupted flag inside the task itself. The code would be something like:

@Autowired
private ThreadPoolTaskExecutor executor;

// ...

Future<?> future = executor.submit(() -> {

  doOneThing();

  if(Thread.interrupted()) {
    return;
  }

  doAnotherThing();

  if(Thread.interrupted()) {
    return;
  }

  // etc.
});

Thread.sleep(10000);

if (!future.isDone()) {
  future.cancel(true);
}
like image 50
Sergei Avatar answered Jan 20 '26 04:01

Sergei



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!