I have a usecase to track execution time of a method in springboot. If execution time exceeds the specific time then I need to throw an exception. I am looking for options to handle that in java and springboot. The method has interaction with redis cache something like mentioned below. Also the important aspect of this usecase is that exception should be thrown without any error in the calling method but purely based on execution time without capturing end time.
public CacheResponse getValue(String key) {
try{
return redisJedisTemplate.opsForValue().get(key);
} catch(Exception e){
LOGGER.error("{}: Error fetching data with key {} {}", className,key,e.getMessage());
return null;
}
}
You should use CompletableFuture with Executor service, in this case:
Here is an example code below :
import java.util.concurrent.*;
public class TimeoutWrapper {
private static final long MAX_EXECUTION_TIME = 1000; // in milliseconds
private final ExecutorService executor = Executors.newSingleThreadExecutor();
public <T> T executeWithTimeout(Callable<T> task) throws ExecutionTimeExceededException {
Future<T> future = executor.submit(task);
try {
return future.get(MAX_EXECUTION_TIME, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
future.cancel(true);
throw new ExecutionTimeExceededException("Method execution exceeded the maximum allowed time of " + MAX_EXECUTION_TIME + " ms");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
With
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
@Service
public class CacheService {
@Autowired
private RedisTemplate<String, CacheResponse> redisJedisTemplate;
private final TimeoutWrapper timeoutWrapper = new TimeoutWrapper();
public CacheResponse getValue(String key) {
try {
return timeoutWrapper.executeWithTimeout(() -> redisJedisTemplate.opsForValue().get(key));
} catch (ExecutionTimeExceededException e) {
LOGGER.error("{}: Execution time exceeded for key {} {}", className, key, e.getMessage());
return null;
} catch (Exception e) {
LOGGER.error("{}: Error fetching data with key {} {}", className, key, e.getMessage());
return null;
}
}