Skip to content

Conversation

@nicojs
Copy link
Contributor

@nicojs nicojs commented Nov 7, 2025

Description

Resolves #8852

Please don't delete this checklist! Before submitting the PR, please make sure you do the following:

  • It's really useful if your PR references an issue where it is discussed ahead of time. If the feature is substantial or introduces breaking changes without a discussion, PR might be closed.
  • Ideally, include a test that fails without this PR but passes with it.
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.
  • Please check Allow edits by maintainers to make review process faster. Note that this option is not available for repositories that are owned by Github organizations.

Tests

  • Run the tests with pnpm test:ci.

Documentation

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs command.

(no new functionality)

Changesets

  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.

@netlify
Copy link

netlify bot commented Nov 7, 2025

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit d017c32
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/690e00fa8d631f000870e520
😎 Deploy Preview https://deploy-preview-8971--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify
Copy link

netlify bot commented Nov 7, 2025

Deploy Preview for vitest-dev ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit a791707
🔍 Latest deploy log https://app.netlify.com/projects/vitest-dev/deploys/6911aa5a6ddcd600082ba35d
😎 Deploy Preview https://deploy-preview-8971--vitest-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@nicojs
Copy link
Contributor Author

nicojs commented Nov 7, 2025

I don't know why the tests are failing. @sheremet-va any idea?

@sheremet-va
Copy link
Member

I don't know why the tests are failing. @sheremet-va any idea?

They are flaky. If you didn't touch them, don't worry.

As a note, your test needs to be inside test/cli, tests are separated in groups, see test/README

@nicojs
Copy link
Contributor Author

nicojs commented Nov 8, 2025

Thanks for the review! 🙏

I've moved the test to test/cli.

@nicojs
Copy link
Contributor Author

nicojs commented Nov 10, 2025

@sheremet-va I've improved the test, made it silent, assert happy path and clarified with some comments. What do you think?

Comment on lines +50 to +52
// Wait for any ongoing cancellation to complete before accepting new tasks
if (this.cancellingPromise) {
await this.cancellingPromise
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if this change will start some previous run's tests too. I have no idea why this._isCancelling was required before - @sheremet-va I think that's something you added?

Copy link
Member

Choose a reason for hiding this comment

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

I have no idea why this._isCancelling was required before

The comment explains it:

Prevent new tasks from being queued during cancellation

Copy link
Member

@sheremet-va sheremet-va Nov 10, 2025

Choose a reason for hiding this comment

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

These kinds of checks exist to catch any unintended behaviours

Copy link
Member

Choose a reason for hiding this comment

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

Now that we just await here and then let it continue, doesn't it mean it's going to continue the run it was intended the cancel? Should it return instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, that was the previous cancellation (because of bail). So it needs to wait for that to finish.

Comment on lines -170 to -171
// Set flag to prevent new tasks from being queued
this._isCancelling = true
Copy link
Member

Choose a reason for hiding this comment

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

Pool should already have had all tests queued at this point. Or if there was another group, the ctx.isCancelling in node/pool.ts should have prevented them from being queued.

Copy link
Member

Choose a reason for hiding this comment

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

If this was true, there wouldn't have been an issue #8852

Copy link
Member

@AriPerkkio AriPerkkio left a comment

Choose a reason for hiding this comment

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

To me this looks more like race condition in core.ts:

We start cancelling here:

this.isCancelling = true

And it's then overwritten by

// previous run
await this.runningPromise
this._onCancelListeners = []
this.isCancelling = false

This is noticable with your reproduction. No idea why that happens.

@nicojs
Copy link
Contributor Author

nicojs commented Nov 10, 2025

@AriPerkkio I now use your implementation with rounds >= 2, however the race condition will almost never happen within the first 3 rounds. Should we make it maybe 20 rounds to make sure?

I've implemented the changes requested by @sheremet-va

@AriPerkkio I'm not familiar enough with the code base to know how cancellation in core.ts is supposed to work. Maybe @sheremet-va knows the answer?

test('cancels previous run before starting new one', async () => {
const results: Record<string, unknown>[] = []

const { ctx: vitest, buildTestTree } = await runVitest({
Copy link
Member

Choose a reason for hiding this comment

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

Does this bug reproduce with runVitest? I'm only able to see it via createVitest.

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 get reproduce it structurally, as long as I use pool: 'threads'

@AriPerkkio
Copy link
Member

The underlying bug is rather in core.ts that keeps starting new runs even though it's still cancelling previous ones. I've pushed those fixes in #8991 to avoid overwriting changes in this PR.

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.

Race condition in new pool implementation when using bail

3 participants