【发布时间】:2015-05-21 02:50:32
【问题描述】:
我有一个带有 WebAsyncTask 的控制器。此外,我正在使用超时回调。 正如 here 所写,我可以选择通知 Callable 取消处理。但是,我看不到任何这样做的选择。
@Controller
public class UserDataProviderController {
private static final Logger log = LoggerFactory.getLogger(UserDataProviderController.class.getName());
@Autowired
private Collection<UserDataService> dataServices;
@RequestMapping(value = "/client/{socialSecurityNumber}", method = RequestMethod.GET)
public @ResponseBody
WebAsyncTask<ResponseEntity<CustomDataResponse>> process(@PathVariable final String socialSecurityNumber) {
final Callable<ResponseEntity<CustomDataResponse>> callable = new Callable<ResponseEntity<CustomDataResponse>>() {
@Override
public ResponseEntity<CustomDataResponse> call() throws Exception {
CustomDataResponse CustomDataResponse = CustomDataResponse.newInstance();
// Find user data
for(UserDataService dataService:dataServices)
{
List<? extends DataClient> clients = dataService.findBySsn(socialSecurityNumber);
CustomDataResponse.put(dataService.getDataSource(), UserDataConverter.convert(clients));
}
// test long execution
Thread.sleep(4000);
log.info("Execution thread continued and shall be terminated:"+Thread.currentThread().getName());
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
return new ResponseEntity(CustomDataResponse,responseHeaders,HttpStatus.OK);
}
};
final Callable<ResponseEntity<CustomDataResponse>> callableTimeout = new Callable<ResponseEntity<CustomDataResponse>>() {
@Override
public ResponseEntity<CustomDataResponse> call() throws Exception {
// Error response
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(new MediaType("application", "json", Charset.forName("UTF-8")));
return new ResponseEntity("Request has timed out!",responseHeaders,HttpStatus.INTERNAL_SERVER_ERROR);
}
};
WebAsyncTask<ResponseEntity<CustomDataResponse>> task = new WebAsyncTask<>(3000,callable);
task.onTimeout(callableTimeout);
return task;
}
}
我的@WebConfig
@Configuration
@EnableWebMvc
class WebAppConfig extends WebMvcConfigurerAdapter {
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setKeepAliveSeconds(60 * 60);
executor.afterPropertiesSet();
configurer.registerCallableInterceptors(new TimeoutCallableProcessingInterceptor());
configurer.setTaskExecutor(executor);
}
}
而且相当标准的拦截器:
public class TimeoutCallableProcessingInterceptor extends CallableProcessingInterceptorAdapter {
@Override
public <T> Object handleTimeout(NativeWebRequest request, Callable<T> task) {
throw new IllegalStateException("[" + task.getClass().getName() + "] timed out");
}
}
一切正常,但来自控制器的 Callable 总是完成,这很明显,但是如何停止那里的处理?
【问题讨论】:
-
你的意思是需要 4 秒的 callable 不会在 3 秒后停止?
-
是的。基本上我不希望在睡眠后执行任何代码。
-
@Premek 就是这样。您必须手动处理中断,即从数据服务返回结果的可调用对象应检查它是否收到中断信号,并在您的情况下通过发送另一个响应来对其采取行动。
-
@Magnamag 你的意思是像 call:
Thread.currentThread().interrupt();in callableTimout 并在控制器中检查它,比如` if (Thread.currentThread().isInterrupted()){` 我不确定这是正确的方法...
标签: java spring spring-mvc timeout asynccallback