Sometimes you have a segment of code that you want to kill if it runs any longer than a specified time period, for example a database query, external API call, or other type of long-running request.
To do this, you want to wrap the block of code to time out in a Callable
, and use the ExecutorService
to execute the code with a time limit. It will return an array of Future
objects, which you can then reference with the .get()
method to retrieve the Callable
return value.
In your build.gradle file, you will need to include the Grails Executor plug-in if you want to have any GORM/Hibernate functionality in your Callable
statement.
compile "org.grails.plugins:grails-executor:0.4"
You can then use the following code to put a timeout on your executing code. When the timeout is reached, the thread that was spawned is terminated.
class CallableTestService {
ExecutorService executorService
Object performAction() {
def callable = ({
// do some logic here
def resultValue = true
// return the value
return resultValue
} as Callable<Object>)
def callables = [callable]
def result = null
try {
def timeLimitMS = 1000
def futures = this.executorService.invokeAll(callables, timeLimitMS, TimeUnit.MILLISECONDS)
def future = futures?.first()
result = future.get()
} catch (error) {
// error handling goes here
}
// do something with the result
return result
}
}