-
Notifications
You must be signed in to change notification settings - Fork 2k
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
client: ensure task only runs with prestart hooks #18662
Conversation
Since the allocation in the task runner is updated in a separate goroutine, a race condition may happen where the task is started but the prestart hooks are skipped because the allocation became terminal. Checking for a terminal allocation before proceeding with the task start ensures the task only runs if the prestart hooks are also executed. Since `shouldShutdown()` only uses terminal allocation status, it remains `true` after the first transition, so it's safe to check it again after the prestart hooks as it will never revert to `false`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Sad that shouldShutdown()
really means "should-shutdown-because-alloc-is-terminal" ... I think it would be safe to stuff the killCtx and shutdownCtx checks inside of it as well, but then we have to consider what that would do in the checks that call shouldShutdown()
. So this seems like a nice precise fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch!
Yeah, I wanted to make this part of the code more "transactional": either the task starts in full or it doesn't start at all. But that would be a much bigger change I think, so I went for the smaller change necessary to fix the problem. |
Since the allocation in the task runner is updated in a separate goroutine, a race condition may happen where the task is started but the prestart hooks are skipped because the allocation became terminal.
Checking for a terminal allocation before proceeding with the task start ensures the task only runs if the prestart hooks are also executed.
Since
shouldShutdown()
only uses terminal allocation status, it remainstrue
after the first transition, so it's safe to check it again after the prestart hooks as it will never revert tofalse
.Some other implementations ideas I considered:
shouldShutdown()
from withinprestart()
to before it is called. I think this would be more or less equivalent to this approach.shouldShutdown()
is guaranteed not to change whileprestart()
runs and the task starts. This is probably the most "correct" approach, but sinceshouldShutdown()
can only transition fromfalse
totrue
, checking it again afterprestart()
seems enough.Closes #18659