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

Move taskqueue to mapping layer #1069

Merged
merged 17 commits into from
Oct 23, 2023
Merged

Move taskqueue to mapping layer #1069

merged 17 commits into from
Oct 23, 2023

Conversation

ankur22
Copy link
Collaborator

@ankur22 ankur22 commented Oct 16, 2023

What?

This PR moves the taskqueue to the mapping layer. The change will affect page.on and browserContext.waitForEvent.

Why?

As we work more with goja and it's runtime, it is starting to find its way into our business logic code. This make maintaining the project more difficult due to having to work with raw goja.Value and (more recently) the event loop and taskqueue. One of these areas that we do not want in the business logic is most definitely the taskqueue which was introduced when we added page.on. page.on requires a predicate method on the goja runtime since the function is written in JS. Since the goja runtime is not thread safe we need to work with the taskqueue. Working with the taskqueue in the business logic makes reasoning, maintaining and writing tests very tricky since various components need to be orchestrated in multiple goroutines.

This change forces the creation and deletion of the taskqueue in the mapping layer. This change also forces us to convert goja.Values to native go structs, which has enabled us to move some goja code out of the business logic (specifically for browsercontext.waitForEvent). We can verify that the changes work with JS test scripts, whereas the business logic can be tested with native go code using either unit or integration tests with less go routine orchestration.

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)

@ankur22 ankur22 marked this pull request as draft October 16, 2023 09:31
@ankur22 ankur22 force-pushed the poc/tq-to-mapping branch 8 times, most recently from be41b64 to f3bda45 Compare October 17, 2023 16:05
browser/mapping.go Outdated Show resolved Hide resolved
@ankur22 ankur22 marked this pull request as ready for review October 17, 2023 16:12
Copy link
Collaborator

@ka3de ka3de left a comment

Choose a reason for hiding this comment

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

Thank you for working on this @ankur22 !
Overall I think it looks good, it's true that we are adding complexity to the mapping layer, which ideally it's not desired, but it's a tradeoff in order to simplify our core logic, so I think it's probably a good step forward.

tests/browser_context_test.go Outdated Show resolved Hide resolved
browser/mapping.go Outdated Show resolved Hide resolved
browser/mapping.go Outdated Show resolved Hide resolved
inancgumus
inancgumus previously approved these changes Oct 19, 2023
Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

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

It's great that we're moving toward a more straightforward, more maintainable code base 👍 Thanks!

common/page.go Outdated Show resolved Hide resolved
tests/browser_context_test.go Outdated Show resolved Hide resolved
Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

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

One more point :)

tests/browser_context_test.go Outdated Show resolved Hide resolved
Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

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

🚀

Copy link
Collaborator

@ka3de ka3de left a comment

Choose a reason for hiding this comment

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

LGTM.

Removes the goja TaskQueue from the page implementation and instead
places it in the mapping layer by wrapping the handler in a function
that will execute it in the local TaskQueue.
It's no longer required to return an error from the handler, as this is
handled in the TaskQueue wrapper in the mapping layer.

This change also refactors the test so that:
1. it no longer returns an error from the handler;
2. the event loop has been removed since the taskqueue has been removed
   from the business logic, making the test simpler to understand with
   less orchestration.
With this change we only use the TaskQueue from the main thread, as it's
required to avoid race conditions with goja. Unfortunately this implies
an explicit close call for the TaskQueue that we are wrapping in the
page.close() call in the mapping layer.
To enable us to work with the task queue outside of the business logic
and allow the setup of the predicate function within the task queue
we need to:
1. Parse the options in the mapping layer.
2. Create a func that can call the predicate function from within a
   taskqueue.
3. We need to wait for the taskqueue call to complete and return the
   response back to the caller.
4. Change the browserContext API within the go code.
This refactors the tests so that it matches the new signature for
waitForEvent, which is that it takes in a predicate method and a
timeout.

The predicate method will now be wrapped and added to a taskqueue in
the mapping layer which means we do not need to work with the event
loop in the test itself.

Since the options are now parsed in the mapping layer, this also
simplifies how we pass the predicate and timeout arguments to
waitForEvent.
This is just cleaning up the arguments so that they are grouped in a
better way, as well as shortening the line length to avoid the linter
issue.
Since waitForEvent is a promisified function, we need to make the
taskqueue thread safe.
The taskqueue wasn't working when it was one per vu since it became
difficult to understand exactly when it was best to close the taskqueue
if there were multiple pages.

This change now creates a taskqueue per page, but the taskqueues is
stored in the vu rather than in the page struct itself, which helps
ensure that the taskqueue is kept away from the page business logic.
This will be used to register, retrieve and close the taskqueues which
is required by the page.on and browserContext.waitForEvent APIs.
Since a require.True will FailNow in the current goroutine and not the
root goroutine of the test, it's best to pass an error back to assert
on in the test's root goroutine.
@ankur22 ankur22 merged commit 49a72e1 into main Oct 23, 2023
14 checks passed
@ankur22 ankur22 deleted the poc/tq-to-mapping branch October 23, 2023 10:03
@inancgumus inancgumus added productivity Issues and PRs that improve our productivity refactor labels Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
productivity Issues and PRs that improve our productivity refactor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants