Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@kyri-petrou
Copy link
Contributor

/fixes #9807

The main issue here is that in cases where the shutdown hooks were taking some time to process, the fiber.join would win the race and the thrown Exception (in this case the interruption exception) would be thrown in the main thread. The fix is to make sure that all errors in workflow are caught (by using exitWith instead of onExit, and gracefully close the application with exit(exitCode) after we join the forked fiber.

I also made some cleanups in the logic so that it's easier to follow, since the code previously relied on unsafely running effects unnecessarily and was harder to follow terms of what was executed in what sequence

@kyri-petrou kyri-petrou requested a review from hearnadam April 28, 2025 05:29
hearnadam
hearnadam previously approved these changes Apr 28, 2025
Copy link
Collaborator

@hearnadam hearnadam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if it was possible to test, but...

fiber <- workflow.interruptible.exitWith { exit0 =>
val exitCode = if (exit0.isSuccess) ExitCode.success else ExitCode.failure
// If we're shutting down due to an external signal, the shutdown hook will fulfill the promise
// Otherwise it means we're shutting down due to normal completion and we need to fulfill the promise
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leftover promise comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

"Check the logs for more details and consider overriding `Runtime.reportFatal` to capture context."
)
} else {
try {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this still need to be in a try?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an extremely low chance (I can't reproduce, but theoretically it might be possible), that the submission of the task to the executor is rejected (due to shutdown) and throws a RejectedExecutionException.

As I said, I'm not even sure if that's possible but just wanted to be extra safe just in case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment to clarify

@kyri-petrou kyri-petrou merged commit 1e6a301 into zio:series/2.x Apr 29, 2025
18 checks passed
@kyri-petrou kyri-petrou deleted the fix-race-condition-on-app-shutdown branch April 29, 2025 07:39
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.

Unclean shutdown as a result of a race between shutdown hooks

2 participants