3

While using the embedded tomcat for deploying my spring boot app, I set the async timeout as follows:

@Bean
public EmbeddedServletContainerFactory servletContainer() {
    TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
    factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {

        @Override
        public void customize(Connector connector) {
            connector.setAsyncTimeout(60000);
        }
    });
    return factory;
}

But,how to achieve the same when deploying to an external server, for example, websphere?

Tried using the property:

spring.mvc.async.request-timeout=600000

But this did not have any effect.

Edit:

I had tried implementing AsyncConfigurer as per Andrei's suggestion. But it did not work as expected. Below is my configuration class:

@SpringBootApplication
@EnableAsync
 public class Application implements AsyncConfigurer {

public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
}

@Override
public Executor getAsyncExecutor() {
    Executor executor = new ThreadPoolExecutor(10, 20, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10),
            new ThreadPoolExecutor.AbortPolicy());
    return executor;
}

@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
    // TODO Auto-generated method stub
    return new SimpleAsyncUncaughtExceptionHandler();
}
 }

I have given timeout as 60 seconds, but when trying this configuration, the request was timing out after 30 seconds. Was using RestClient.

Is there something I am missing?

bidisha mukherjee
  • 715
  • 1
  • 10
  • 20

1 Answers1

0

In the SpringApplication (implement first the interface called AsyncConfigurer) class I would create my custom AsyncExeuctor like this:

    @Override
    public Executor getAsyncExecutor() {
        Executor executor = new ThreadPoolExecutor(
                poolSize,
                maxSize,
                keepAlive, 
                TimeUnit.SECONDS, // <--- TIMEOUT IN SECONDS 
                new ArrayBlockingQueue<>(qSize),
                new ThreadPoolExecutor.AbortPolicy() // <-- It will abort if timeout exceeds
        );
        return executor;
    }

You can configure the poolSize, maxSize, etc. in the application.properties file and then "inject" them using the @Value annotation.

Andrei Ciobanu
  • 12,500
  • 24
  • 85
  • 118
  • Is there a way to do this the Spring Boot way, i mean not implementing the AsynCConfigurer, and directly writing some config in the class marked with @SpringBootApplication? – bidisha mukherjee Oct 13 '16 at 09:38
  • @bidishamukherjee The code snippet is from the class marked with `@SpringBootApplication`. That class needs to implement AsyncConfigurer. – Andrei Ciobanu Oct 13 '16 at 10:59
  • Ok got it. But can you also shed some light on why setting spring.mvc.async.request-timeout property did not work? Thanks for the answer already given. – bidisha mukherjee Oct 13 '16 at 11:15
  • @bidishamukherjee I don't know about this property... I never used it. – Andrei Ciobanu Oct 13 '16 at 14:32
  • Tried your way, but it did not work for me. Added my config class. Can you please take a look? – bidisha mukherjee Oct 19 '16 at 10:58
  • are you calling the methods marked with @Async from other methods of the same class ? – Andrei Ciobanu Oct 19 '16 at 13:11
  • Actually I don't have any methods marked with @Async. I have a controller returning DeferredResult, from which I call different methods using reactor EventBus. And the config for internal tomcat server that I posted gives me the intended Async timeout alright. – bidisha mukherjee Oct 24 '16 at 09:22
  • This is not right. The keep alive time is to destroy threads without tasks assigned in the given time (i.e. threads not being used, usually above the core pool size), but that is not a task timeout. – David G. Apr 09 '21 at 08:34