[[namespace-taskscheduler]]
= Configuring the Task Scheduler

In Spring Integration, the `ApplicationContext` plays the central role of a message bus, and you need to consider only a couple of configuration options.
First, you may want to control the central `TaskScheduler` instance.
You can do so by providing a single bean named `taskScheduler`.
This is also defined as a constant, as follows:

[source,java]
----
IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME
----

By default, Spring Integration relies on an instance of `ThreadPoolTaskScheduler`, as described in the https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling[Task Execution and Scheduling] section of the Spring Framework reference manual.
That default `TaskScheduler` starts up automatically with a pool of ten threads, but see xref:configuration/global-properties.adoc[Global Properties].
If you provide your own `TaskScheduler` instance instead, you can set the 'autoStartup' property to `false` or provide your own pool size value.

When polling consumers provide an explicit task executor reference in their configuration, the invocation of the handler methods happens within that executor's thread pool and not the main scheduler pool.
However, when no task executor is provided for an endpoint's poller, it is invoked by one of the main scheduler's threads.

CAUTION: Do not run long-running tasks on poller threads.
Use a task executor instead.
If you have a lot of polling endpoints, you can cause thread starvation, unless you increase the pool size.
Also, polling consumers have a default `receiveTimeout` of one second.
Since the poller thread blocks for this time, we recommend that you use a task executor when many such endpoints exist, again to avoid starvation.
Alternatively, you can reduce the `receiveTimeout`.

NOTE: An endpoint is a Polling Consumer if its input channel is one of the queue-based (that is, pollable) channels.
Event-driven consumers are those having input channels that have dispatchers instead of queues (in other words, they are subscribable).
Such endpoints have no poller configuration, since their handlers are invoked directly.

[IMPORTANT]
=====
When running in a JEE container, you may need to use Spring's `TimerManagerTaskScheduler`, as described https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#scheduling-task-scheduler-implementations[here], instead of the default `taskScheduler`.
To do so, define a bean with the appropriate JNDI name for your environment, as the following example shows:

[source,xml]
----
<bean id="taskScheduler" class="org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler">
    <property name="jndiName" value="tm/MyTimerManager" />
    <property name="resourceRef" value="true" />
</bean>
----
=====

IMPORTANT: When a custom `TaskScheduler` is configured in the application context (like the above mentioned `DefaultManagedTaskScheduler`), it is recommended to supply it with a `MessagePublishingErrorHandler` (`integrationMessagePublishingErrorHandler` bean) to be able to handle exceptions as `ErrorMessage`s sent to the error channel, as is done with the default `TaskScheduler` bean provided by the framework.

See also xref:scatter-gather.adoc#scatter-gather-error-handling[Error Handling] for more information.

