Skip to content
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

Refactor parsing of arguments for waitForFunction #1183

Merged
merged 15 commits into from
Jan 25, 2024

Conversation

ankur22
Copy link
Collaborator

@ankur22 ankur22 commented Jan 23, 2024

What?

Refactor the parsing of the arguments of waitForFunction APIs so that they are done outside the promise and therefore on the main goja thread.

Why?

This will help mitigate issues which can occur when trying to access the goja runtime from multiple goroutines, which can causes panics since the goja runtime is not thread safe.

Checklist

  • I have performed a self-review of my code
  • I have added tests for my changes
  • I have commented on my code, particularly in hard-to-understand areas

Related PR(s)/Issue(s)

Updates: #1180 & #1181

@ankur22 ankur22 changed the base branch from main to main-next January 23, 2024 13:11
@ankur22 ankur22 changed the base branch from main-next to refactor/page-click-parse January 23, 2024 13:14
@@ -457,6 +465,39 @@ func mapFrame(vu moduleVU, f *common.Frame) mapping {
return maps
}

func parseWaitForFunctionArgs(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure about this. Should i just copy and paste the parsing instead of trying to abstract them out into its own function?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I prefer to keep it this way, grouped in a separate function, instead of having it scattered around the mappings implementation. Also considering that this is called more than once, for mapPage and mapFrame.

browser/mapping.go Outdated Show resolved Hide resolved
@ankur22 ankur22 force-pushed the refactor/waitForFunction branch 4 times, most recently from 8eae5b8 to df6c88f Compare January 23, 2024 13:24
@ankur22 ankur22 force-pushed the refactor/page-click-parse branch 2 times, most recently from 9cbdd2f to d57dba3 Compare January 23, 2024 14:05
Base automatically changed from refactor/page-click-parse to main-next January 23, 2024 14:16
Refactor the parsing of the optional options out of the
frame.waitForFunction promise, and move it into the mapping layer which
is on the main goja thread and out of the promise. This will mitigate
the risk of accessing the non thread safe goja runtime from more than
one goroutine.

This change also adds a temporary change in page.waitForFunction to
parse the goja value, which will also change at a later stage.
Move the transformation of the goja callable to a string outside of the
promise for frame.waitForFunction. This is to avoid using the non
thread safe goja runtime from multiple goroutines.

This change also includes a temporary change to page.waitForFunction
which will still do the transformation in the promise for now.
This moves the transformation of the args for the frame.waitForFunction
API to the mapping layer and out of the promise. This will help
mitigate the risk of using the non thread safe goja runtime from
multiple goroutines, and only work with it from the main goja thread in
the mapping layer.

This adds a temporary change to page.waitForFunction where it still
does the transform within the promise. This will be moved at a later
stage.
This method will be used by both frame and page types to parse the
argument for their respective waitForFunction methods.
Use the new parseWaitForFunctionArgs in frame.waitForFunction.
This function is quite useful elsewhere that requires running async
js scripts.
This new function is to only be used by integration tests when needing
to test the mapping layer along with the core business logic for page.
This refactors the parsing of the arguments out of the promise and into
the mapping layer, just as we have done for frame.waitForFunction. This
will help mitigate any issues where we try to access the goja runtime
from multiple goroutines which is not thread safe.
This function will be used by TestPageWaitForFunction. That test
requires access to the mapped versions of page. Instead of exporting a
new MapPage method in mapping.go, work with the existing method to
create a new module instance, set the mapped browser to the runtime
and work with the event system.
This is a custom function for TestWaitForFunction to allow it to run
the async API in an event loop.
The test now works with startIteration and runJSInEventLoop.
This is no longer needed since TestWaitForFunction now works with the
existing workflow on mapping the desired values.
This change was made to allow TestWaitForFunction to work with the same
method to run js code in an eventloop, but it now uses its own method.
tests/page_test.go Outdated Show resolved Hide resolved
tests/page_test.go Outdated Show resolved Hide resolved
Add the test runtime to the k6test.VU type. This is useful when needing
to run async js functions on the goja runtime's event loop within a
test.
This refactors the waitForFunction tests to use the test runtime which
already has a built in helper method to run js on the goja runtime's
event loop.
@ankur22 ankur22 merged commit 71665bf into main-next Jan 25, 2024
14 checks passed
@ankur22 ankur22 deleted the refactor/waitForFunction branch January 25, 2024 11:05
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.

None yet

4 participants