Skip to content

Adjust ThreadPoolTaskScheduler bean registration to use Integer.MAX_VALUE / 2 phase #8856

Closed
@artembilan

Description

@artembilan

Starting with Spring Framework 6.1 the ExecutorConfigurationSupport now supports a lifecycle management.
It comes with a private int phase = DEFAULT_PHASE;.
It has this logic:

	/**
	 * Pause this executor, triggering the given callback
	 * once all currently executing tasks have completed.
	 * @since 6.1
	 */
	@Override
	public void stop(Runnable callback) {
		if (this.lifecycleDelegate != null && !this.lateShutdown) {
			this.lifecycleDelegate.stop(callback);
		}
		else {
			callback.run();
		}
	}

So, it waits for scheduled tasks to be finished.
The AbstractPollingEndpoint uses Integer.MAX_VALUE / 2 and calls this.runningTask.cancel(true); in its stop(). So, no new messages are emitted to the application.
However this combination leads to dead-lock and unexpected behavior.
According to the phase logic

	 * The default phase for {@code SmartLifecycle}: {@code Integer.MAX_VALUE}.
	 * <p>This is different from the common phase {@code 0} associated with regular
	 * {@link Lifecycle} implementations, putting the typically auto-started
	 * {@code SmartLifecycle} beans into a later startup phase and an earlier
	 * shutdown phase.

The ThreadPoolTaskScheduler is stopped earlier, then PollingConsumer.
And the former waits for its tasks to be finished, not giving the later a chance to cancel its task.

Therefore the ThreadPoolTaskScheduler configuration in the DefaultConfiguringBeanFactoryPostProcessor.registerTaskScheduler() should be adjusted to use the same Integer.MAX_VALUE / 2 phase.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions