Creating a thread to run timeout tasks in the Spring web server

I am trying to create a thread that starts a task set and, if it does not complete within a certain time (for example, 100 seconds), throws an exception. I'm currently trying to do this by encapsulating tasks in a runnable object and using the ExecutorService and Future classes to execute timeouts. However, when I start my web service, I get this exception:

 java.util.concurrent.ExecutionException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.localhostInterpolatorHealthCheck': Scope 'request' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. at java.util.concurrent.FutureTask.report(FutureTask.java:122) at java.util.concurrent.FutureTask.get(FutureTask.java:202) 

I read online that it is not as simple as defining your own threads and running them to start the thread on Spring, so I am wondering how to do this? What am I missing?

+8
java spring multithreading spring-mvc
source share
2 answers

Try the following:

  /** * Executes a task with a specified timeout. */ public final class TimeoutController { /** * Do not instantiate objects of this class. Methods are static. */ private TimeoutController() { } /** * Executes <code>task</code>. Waits for <code>timeout</code> * milliseconds for the task to end and returns. If the task does not return * in time, the thread is interrupted and an Exception is thrown. * The caller should override the Thread.interrupt() method to something that * quickly makes the thread die or use Thread.isInterrupted(). * @param task The thread to execute * @param timeout The timeout in milliseconds. 0 means to wait forever. * @throws TimeoutException if the timeout passes and the thread does not return. */ public static void execute(Thread task, long timeout) throws TimeoutException { task.start(); try { task.join(timeout); } catch (InterruptedException e) { /* if somebody interrupts us he knows what he is doing */ } if (task.isAlive()) { task.interrupt(); throw new TimeoutException(); } } /** * Executes <code>task</code> in a new deamon Thread and waits for the timeout. * @param task The task to execute * @param timeout The timeout in milliseconds. 0 means to wait forever. * @throws TimeoutException if the timeout passes and the thread does not return. */ public static void execute(Runnable task, long timeout) throws TimeoutException { Thread t = new Thread(task, "Timeout guard"); t.setDaemon(true); execute(t, timeout); } /** * Signals that the task timed out. */ public static class TimeoutException extends Exception { /** Create an instance */ public TimeoutException() { } } } 
+3
source share

Instead, you can use several @async methods, and then run them from the main code stream, get a list of futures. After skipping the timeout, you can get the result or stop the execution (cancel / end).

This has advantages, since you will name spring managed beans, so all the properties nested in the dependency will be available to you. But you have to be careful with the number of jobs / threads you submit.

To use the @async annotation, you need to enable asynchronous stuff using either a specific line in your xml configuration or an AsyncEnabled annotation on a bean.

+1
source share

All Articles