spring MVC Callable execution continues even after

2019-05-18 17:26发布

I have an Asynchronous handlermethod like this

@RequestMapping("/custom-timeout-handling")
public @ResponseBody WebAsyncTask<String> callableWithCustomTimeoutHandling() {

    Callable<String> callable = new Callable<String>() {

        public String call() throws Exception {
            while(i==0){
            System.out.println("inside while loop->");
            }

            return "Callable result";
        }
    };

    return new WebAsyncTask<String>(10000, callable);
}

which will execute the while loop until the specified timeout(10sec).

When the request is timeout,it executes the handleTimeout method from TimeoutCallableProcessingInterceptor

public class TimeoutCallableProcessingInterceptor extends CallableProcessingInterceptorAdapter {

@Override
public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) throws Exception {
    throw new IllegalStateException("[" + task.getClass().getName() + "] timed out");
}

}

Source:i have replaced

Thread.sleep(2000)

with

while(i==0){
System.out.println("inside while loop->");
}

My problem is even after timeout(finished executing handle timeout method)response is send from handletimeout method the while loop is still processing until the value of i is changed to some other value other than zero.

Is the request is still held by the server?then what is the use of request timeout?

Thanks in advance...

1条回答
太酷不给撩
2楼-- · 2019-05-18 17:55

When a servlet container thread detects that a async callable has timed-out, it invokes handleTimeout() (in its own context). Thats the reason you see the handleTimeout() getting executed. It is executed by a servlet container thread and not by the thread that runs the Callable.

If you want custom timeout handling, you need to do two things:

  1. Override onTimeout() in your WebAsyncTask. Whatever callable you provide as the callback to onTimeout() will be invoked within a servlet container thread when it detects your callable has timed-out.
  2. Check for timeouts/interruptions in the Callable you have created inside the controller. If your Callable does not expect and respect interruption ("If the target thread does not poll the interrupted status the interrupt is effectively ignored"), there is no way to interrupt it! Pls refer this answer to know how to expect and respect interruption.
查看更多
登录 后发表回答