Skip to content

Recursive sync watcher stops tracking computed #12033

@skirtles-code

Description

@skirtles-code

Vue version

3.5.6

Link to minimal reproduction

https://play.vuejs.org/#eNp9Uctqw0AM/BWxlzjgOC19QXBCH4TSHtrS9rhQ3I2cOFnvmn04KcH/Xq2N0xxKbtLMSMxIe3ZXVUntkU1YaoUpKgcWna9mXBVlpY2DPRjMY9hmTqxiELqsvMMFNJAbXcKAZgdccSW0sg4MTIM8Ohv2iCCkH4qiIUxnYJI6kx5JwlW7NhIxRHXL7bkCKHJqYQbnw66HfmQ0Cm3DVROTr1x6u5rAwP4oMYCG9qXjLgO5p8ZhWcnMIXUAe8oBTQOjUIlQpd/eOa3gVshCbKacBfM3nM0edTruOJpMx0drWMycpVx5sUzWViu6WmuQsxCxkGheK1dQbs4mvXXOMin19rnFnPEY97hYodj8g6/tLmCcvRm0aGrk7MC5zCzRdfT84wV3VB/IUi+8JPUJ8h2tlj547GT3Xi3I9pGudfvU/r5Qy0873zlUtg8VjLY/aPWc0fsfTkT/s3uRXPa/oyt+1WjCTjrgRXKVXLPmFzJo0y8=

Steps to reproduce

Just click the button.

What is expected?

The rendered values should be 1.

What is actually happening?

The rendered values are 6.

System Info

No response

Any additional comments?

This changed in 3.5.6. In 3.5.5 and earlier it renders 1, as expected.

I found this while investigating #11956. I still don't know what causes the memory leak, but after staring at #11944 for a bit I noticed the potential problem I've reported here.

This is what I believe is happening...

When a computed is notified, the NOTIFIED flag gets set for both ComputedRefImpl and its dep. These are queued in a batch. When endBatch() is called it handles the dep first, clearing the NOTIFIED flag from the dep and then calling trigger(). But the NOTIFIED flag is still set for the ComputedRefImpl, so it can't be notified while trigger() is running.

I used watch with flush: 'sync' in the reproduction, as that was the most direct way to take advantage of the mismatched flags. I'm not sure whether there's a more 'normal' way to hit this timing issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    ❗ p4-importantPriority 4: this fixes bugs that violate documented behavior, or significantly improves perf.regressionscope: reactivity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions