All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.web.context.request.async.WebAsyncTask Maven / Gradle / Ivy

There is a newer version: 6.1.6
Show newest version
/*
 * Copyright 2002-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.context.request.async;

import java.util.concurrent.Callable;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.context.request.NativeWebRequest;

/**
 * Holder for a {@link Callable}, a timeout value, and a task executor.
 *
 * @author Rossen Stoyanchev
 * @author Juergen Hoeller
 * @since 3.2
 * @param  the value type
 */
public class WebAsyncTask implements BeanFactoryAware {

	private final Callable callable;

	private Long timeout;

	private AsyncTaskExecutor executor;

	private String executorName;

	private BeanFactory beanFactory;

	private Callable timeoutCallback;

	private Callable errorCallback;

	private Runnable completionCallback;


	/**
	 * Create a {@code WebAsyncTask} wrapping the given {@link Callable}.
	 * @param callable the callable for concurrent handling
	 */
	public WebAsyncTask(Callable callable) {
		Assert.notNull(callable, "Callable must not be null");
		this.callable = callable;
	}

	/**
	 * Create a {@code WebAsyncTask} with a timeout value and a {@link Callable}.
	 * @param timeout a timeout value in milliseconds
	 * @param callable the callable for concurrent handling
	 */
	public WebAsyncTask(long timeout, Callable callable) {
		this(callable);
		this.timeout = timeout;
	}

	/**
	 * Create a {@code WebAsyncTask} with a timeout value, an executor name, and a {@link Callable}.
	 * @param timeout timeout value in milliseconds; ignored if {@code null}
	 * @param executorName the name of an executor bean to use
	 * @param callable the callable for concurrent handling
	 */
	public WebAsyncTask(@Nullable Long timeout, String executorName, Callable callable) {
		this(callable);
		Assert.notNull(executorName, "Executor name must not be null");
		this.executorName = executorName;
		this.timeout = timeout;
	}

	/**
	 * Create a {@code WebAsyncTask} with a timeout value, an executor instance, and a Callable.
	 * @param timeout timeout value in milliseconds; ignored if {@code null}
	 * @param executor the executor to use
	 * @param callable the callable for concurrent handling
	 */
	public WebAsyncTask(@Nullable Long timeout, AsyncTaskExecutor executor, Callable callable) {
		this(callable);
		Assert.notNull(executor, "Executor must not be null");
		this.executor = executor;
		this.timeout = timeout;
	}


	/**
	 * Return the {@link Callable} to use for concurrent handling (never {@code null}).
	 */
	public Callable getCallable() {
		return this.callable;
	}

	/**
	 * Return the timeout value in milliseconds, or {@code null} if no timeout is set.
	 */
	@Nullable
	public Long getTimeout() {
		return this.timeout;
	}

	/**
	 * A {@link BeanFactory} to use for resolving an executor name.
	 * 

This factory reference will automatically be set when * {@code WebAsyncTask} is used within a Spring MVC controller. */ public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } /** * Return the AsyncTaskExecutor to use for concurrent handling, * or {@code null} if none specified. */ @Nullable public AsyncTaskExecutor getExecutor() { if (this.executor != null) { return this.executor; } else if (this.executorName != null) { Assert.state(this.beanFactory != null, "BeanFactory is required to look up an executor bean by name"); return this.beanFactory.getBean(this.executorName, AsyncTaskExecutor.class); } else { return null; } } /** * Register code to invoke when the async request times out. *

This method is called from a container thread when an async request times * out before the {@code Callable} has completed. The callback is executed in * the same thread and therefore should return without blocking. It may return * an alternative value to use, including an {@link Exception} or return * {@link CallableProcessingInterceptor#RESULT_NONE RESULT_NONE}. */ public void onTimeout(Callable callback) { this.timeoutCallback = callback; } /** * Register code to invoke for an error during async request processing. *

This method is called from a container thread when an error occurred * while processing an async request before the {@code Callable} has * completed. The callback is executed in the same thread and therefore * should return without blocking. It may return an alternative value to * use, including an {@link Exception} or return * {@link CallableProcessingInterceptor#RESULT_NONE RESULT_NONE}. * @since 5.0 */ public void onError(Callable callback) { this.errorCallback = callback; } /** * Register code to invoke when the async request completes. *

This method is called from a container thread when an async request * completed for any reason, including timeout and network error. */ public void onCompletion(Runnable callback) { this.completionCallback = callback; } CallableProcessingInterceptor getInterceptor() { return new CallableProcessingInterceptor() { @Override public Object handleTimeout(NativeWebRequest request, Callable task) throws Exception { return (timeoutCallback != null ? timeoutCallback.call() : CallableProcessingInterceptor.RESULT_NONE); } @Override public Object handleError(NativeWebRequest request, Callable task, Throwable t) throws Exception { return (errorCallback != null ? errorCallback.call() : CallableProcessingInterceptor.RESULT_NONE); } @Override public void afterCompletion(NativeWebRequest request, Callable task) throws Exception { if (completionCallback != null) { completionCallback.run(); } } }; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy