Skip to content

k6/browser: Fix race conditions from stringifying types #4794

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

Merged
merged 1 commit into from
May 19, 2025
Merged

Conversation

mstoykov
Copy link
Contributor

What?

Before this in cases like #4564 you can have an error that stringifies ElementHandle object. That object has many other objects inside of it, some of which have maps or other more complex structure. None of which are thread safe to be accessed without locking.

This is very likely the reason for the race conditions in #4564 (maybe other cases as well). In this case we do have ElementHandle as the argument - we get an error due to likely it getting disposed while converting it. And then we start returning an error that has it just stringified. While fmt goes through the object we get another event (maybe exactly the same) modifying one of the many maps within the object - likely under the Frame specifically.

This also likely leads to pretty useless logs due to the amount of fields both have. With this change we only logs some fields that are less likely to be racy, or at least won't lead to a runtime race condition without the race detector being on.

Why?

Fixing race conditions

Checklist

  • I have performed a self-review of my code.
  • I have commented on my code, particularly in hard-to-understand areas.
  • I have added tests for my changes.
  • I have run linter and tests locally (make check) and all pass.

Checklist: Documentation (only for k6 maintainers and if relevant)

Please do not merge this PR until the following items are filled out.

  • I have added the correct milestone and labels to the PR.
  • I have updated the release notes: link
  • I have updated or added an issue to the k6-documentation: grafana/k6-docs#NUMBER if applicable
  • I have updated or added an issue to the TypeScript definitions: grafana/k6-DefinitelyTyped#NUMBER if applicable

Related PR(s)/Issue(s)

Fixes #4564

@mstoykov mstoykov added this to the v1.1.0 milestone May 16, 2025
@mstoykov mstoykov requested a review from a team as a code owner May 16, 2025 08:20
@mstoykov mstoykov requested review from oleiade and ankur22 and removed request for a team May 16, 2025 08:20
@mstoykov
Copy link
Contributor Author

Unfortunately making this race seems ... impossible within a test :( Even the case I have seen takes minutes of fully running load test run with 500 browsers to happen.

Before this in cases like #4564 you can have an error that stringifies
ElementHandle object. That object has many other objects inside of it,
some of which have maps or other more complex structure. None of which
are thread safe to be accessed without locking.

This is very likely the reason for the race conditions in #4564 (maybe
other cases as well). In this case we do have ElementHandle as the
argument - we get an error due to likely it getting disposed while
converting it. And then we start returning an error that has it just
stringified. While fmt goes through the object we get another event
(maybe exactly the same) modifying one of the many maps within the
object - likely under the Frame specifically.

This also likely leads to pretty useless logs due to the amount of
fields both have. With this change we only logs some fields that are
less likely to be racy, or at least won't lead to a runtime race
condition without the race detector being on.

Fixes #4564
// String returns a string repesentation of ElementHandle.
// It exists mostly for debugging where we don't want fmt.Sprintf to just
// go through a complex object and try to stringify it.
func (h *ElementHandle) String() string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these string methods called when a user works with console.log in their test scripts?

If so, I'm wondering if we should try to expose more of the entities/types. Maybe we need to take a look at what is printed when working with Playwright while performing the same console.log call against the ElementHandle -- happy to help if needed.

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 think that due to the mapping files this is nto being called. But I guess that might an interesting thing to check - yes.

But this currently is about when we create errors with fmt.Errorf and friends and that traversing objects that ... likely shouldn't be traversed with some amount of locking and that leading to races.

Your suggestion is about UX whcih is also nice - but I do not know what the expected result is and it likely is bigger topic.

Copy link
Contributor

Choose a reason for hiding this comment

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

Aha, thanks for clarifying 👍

Copy link
Contributor

@ankur22 ankur22 left a comment

Choose a reason for hiding this comment

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

LGTM 🚀

@mstoykov mstoykov merged commit 23e50f3 into master May 19, 2025
32 checks passed
@mstoykov mstoykov deleted the fix4564 branch May 19, 2025 08:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

concurrent map iteration and map write: ExecutionContext.eval
3 participants