Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behaviour change in ScheduledAnnotationBeanPostProcessor: canceling scheduled tasks on ContextClosedEvent v6.0 -> v6.1 #33009

Closed
ansgarschulte opened this issue Jun 11, 2024 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Milestone

Comments

@ansgarschulte
Copy link

Use case:

During Graceful Shutdown, we rely on scheduled tasks being executed until final shutdown. This works with springs v6.0.x and stopped working in v6.1

With this change all scheduled tasks are canceled and continueExistingPeriodicTasksAfterShutdownPolicy of the ThreadPoolTaskScheduler has no effect here.

Here is a spring boot sample application:

@SpringBootApplication
@EnableScheduling
public class DemoApplication implements CommandLineRunner {

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

    @Override
    public void run(String... args) throws Exception {
        System.out.println("Sleeping forever, you can press Ctrl+C to shutdown application");
        while (true) {
            Thread.sleep(1000);
        }
    }

    @Bean
    ThreadPoolTaskSchedulerCustomizer threadPoolTaskSchedulerPhaseCustomizer() {
        return p -> {
            p.setPhase(0);
            p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
            p.setWaitForTasksToCompleteOnShutdown(true);
            p.setAcceptTasksAfterContextClose(true);
            p.setExecuteExistingDelayedTasksAfterShutdownPolicy(true);
            p.setAwaitTerminationSeconds(180);
            p.setPoolSize(4);
            p.setThreadNamePrefix("custom-scheduler-");
        };
    }


    @Scheduled(fixedRate = 1000, scheduler = ScheduledAnnotationBeanPostProcessor.DEFAULT_TASK_SCHEDULER_BEAN_NAME)
    public void test() {
        var pid = System.getProperty("PID");
        System.out.println("Kill me with 'kill -int " + pid + "' - " + Thread.currentThread().getName() + " - " + System.currentTimeMillis());
    }

    @Bean
    SmartLifecycle waitOnShutdown() {
        return new SmartLifecycle() {
            private boolean running;

            @Override
            public void start() {
                this.running = true;
            }

            @Override
            public void stop() {
                var counter = 0;
                System.out.println("Waiting for 10 seconds before stopping");
                do {
                    try {
                        System.out.println("Waiting for 1 second");
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } while (counter++ < 10);
                this.running = true;
            }

            @Override
            public boolean isRunning() {
                return this.running;
            }
        };
    }
}

After sending kill -int xyz to the output of the scheduled task stops.

Our current workaround is to use a custom ScheduledAnnotationBeanPostProcessor ignoring the ContextClosedEvent

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jun 11, 2024
@jhoeller jhoeller self-assigned this Jun 11, 2024
@jhoeller jhoeller added the in: core Issues in core modules (aop, beans, core, context, expression) label Jun 11, 2024
@jhoeller
Copy link
Contributor

It looks like the fix for #24629 is too harsh in assuming that all declaratively scheduled tasks should be cancelled unconditionally on context close. I'll see how we can revise this while still adhering to the target scenario in #24629 as well.

@jhoeller jhoeller added type: regression A bug that is also a regression and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jun 11, 2024
@jhoeller jhoeller added this to the 6.1.9 milestone Jun 11, 2024
@jhoeller
Copy link
Contributor

The revision will be available in the upcoming 6.1.9 snapshot, reducing the early cancellation to non-managed objects while letting regular singleton beans participate in the regular factory destruction arrangement and the scheduler setup. Please give it an early try if you have the chance today, in advance of the actual 6.1.9 release tomorrow...

@ansgarschulte
Copy link
Author

Thx for the fast fix and turnaround. I can confirm that it is working with my test application and setting continueExistingPeriodicTasksAfterShutdownPolicy to false (default value).

@jhoeller
Copy link
Contributor

Good to hear, thanks for the immediate feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) type: regression A bug that is also a regression
Projects
None yet
Development

No branches or pull requests

3 participants