Skip to content

Drain Spring Boot workers during graceful shutdown - #3137

Draft
eamsden wants to merge 1 commit into
mainfrom
ea/sigterm-shutdown
Draft

eamsden wants to merge 1 commit into
mainfrom
ea/sigterm-shutdown

Conversation

@eamsden

@eamsden eamsden commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

What changed?

Manage auto-configured root and non-root worker factories with Spring's SmartLifecycle. Context shutdown initiates WorkerFactory.shutdown() and waits for termination before bean destruction, bounded by spring.lifecycle.timeout-per-shutdown-phase. Retain shutdown cleanup when context initialization fails.

Remove the non-root context-close listener that ignored its own context and instead stopped workers when a child context closed. Keep existing worker startup settings and application control of JVM shutdown hooks.

Document shutdown ownership for standalone factories and Spring Boot applications, and add a changelog entry.

Why?

The JVM already delivers SIGINT and SIGTERM to the same shutdown hooks. Spring's root factory destroy method initiated shutdown without waiting, and non-root factories were not shut down when their own context closed. Both signals could therefore end the process before in-flight activities finished.

Breaking changes?

No existing public API signatures changed. Spring context shutdown now waits for graceful worker termination within its configured lifecycle timeout. The integration continues using orderly shutdown and preserves activity cancellation semantics.

Server PR

None required.

Validation

Run on macOS with the repository's Java 21 toolchain; changed Java sources compile with --release 8.

  • ./gradlew --offline spotlessApply :temporal-spring-boot-autoconfigure:test :temporal-sdk:javadoc :temporal-spring-boot-autoconfigure:javadoc: passed; Spring suite had 49 passed and 2 conditional skips. Both Javadoc tasks passed.
  • ./gradlew --offline :temporal-sdk:test --tests 'io.temporal.worker.WorkerShutdownTest' --tests 'io.temporal.worker.shutdown.*' --tests 'io.temporal.workerFactory.WorkerFactoryTests': 17 passed, 3 external-server tests skipped.
  • New subprocess tests deliver real SIGINT and SIGTERM to child JVMs, for both standalone application hooks and Spring Boot. They hold activities until both factories begin shutdown, then verify activity completion and factory termination. Additional coverage checks explicit context close with JVM hooks disabled, child-context isolation, the lifecycle timeout without task interruption, preexisting shutdown requests, and failed context initialization.
  • Against unchanged upstream Spring lifecycle code, all four Spring subprocess scenarios failed; both standalone signal cases passed. With this change, all nine new regression cases passed, including a final rerun after making PID readiness publication race-free.

The complete multi-module test suite and Linux/Windows runtime execution were not run locally. The Spring suite's conditional skips cover worker versioning (external server required) and OpenTelemetry auto-configuration (Spring Boot 3+ required).

@eamsden
eamsden requested a review from a team as a code owner October 9, 2026 01:13
@eamsden
eamsden marked this pull request as draft October 9, 2026 01:58
@Quinn-With-Two-Ns

Copy link
Copy Markdown
Contributor

There is already a PR open addressing this #3115 I believe

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants