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

Update extension to ModuleV2, minor context changes #57

Merged
merged 2 commits into from
Nov 8, 2021
Merged

Conversation

imiric
Copy link
Contributor

@imiric imiric commented Nov 4, 2021

This updates the JS module to use the new ModuleV2 structure, and reuses the context passed to launch().

It's an initial step towards fixing the panic: send on closed channel mentioned in #49, but it will need some changes on the k6 side to synchronize the k6 Engine shutdown with extensions that use stats.PushIfNotDone(). Likely the proper context will need to be propagated to extensions which doesn't seem to be the case right now.

For background on the ModuleV2 changes take a look at grafana/k6@34a7743fb, grafana/k6#2108, and the "Advanced JavaScript extension" section in https://k6.io/docs/misc/k6-extensions/#writing-a-new-extension. The tldr; is that this is a new way of structuring JS modules that allows them to access internal k6 objects, is a saner alternative to common.Bind() (which we plan to deprecate eventually), and has the wanted side effect that each VU gets a separate instance of the module.

@imiric imiric requested a review from inancgumus November 4, 2021 15:22
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.

LGTM! I don't understand why is this going to help, though (from a newcomer perspective) 😒

main.go Show resolved Hide resolved
main.go Show resolved Hide resolved
main.go Show resolved Hide resolved
}
}

func (m *JSModule) Launch(ctx context.Context, browserName string, opts goja.Value) api.Browser {
// GetExports returns the exports of the JS module.
func (mi *ModuleInstance) GetExports() k6modules.Exports {
Copy link
Member

Choose a reason for hiding this comment

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

I prefer this to be just Exports() instead of Java-like GetExports. But it's been defined in the interface, so 🤷

Why does the JS module need to export? Is it for using the exported modules from JS scripts? Can we extend this comment and explain the why?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, Exports() would be better, but difficult to change now as all extensions would need to be changed as well. The ModuleV2 name is also temporary and we plan to clean this up eventually, so we could consider changing to Exports() then as well.

Why does the JS module need to export?

So that it's actually usable from JS :)

Can we extend this comment and explain the why?

Like I mentioned in the other comment, this is not the place to give the background on the ModuleV2 structure or interfaces. We could expand the documentation in k6 itself (js/modules/modules.go), but the "why" is really answered in that commit and PR I linked to.

Copy link
Member

Choose a reason for hiding this comment

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

I believe it's better to give some (a little) background/reason for an extension developer who is supposed to focus on this extension code only.

Maybe something like:

// GetExports returns the exports of the JS module.
// So that the test scripts can access the exported k6 modules.
// (^-- idk whether this comment is right or wrong. you can provide something better)
func (mi *ModuleInstance) GetExports() k6modules.Exports { ... }

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 expanded the comment slightly in 1976e55.

main.go Outdated Show resolved Hide resolved
Ivan Mirić added 2 commits November 8, 2021 10:39
This is the context passed from k6, and for synchronization purposes it
would be better if the extension depended on it, so that errors like the
`panic: send on close channel` from issue 49 wouldn't happen. This
technically probably doesn't fix that yet, since the context created
in k6 isn't synchronized with the Engine shutdown and closing of the
SampleContainer channel, but it seems like a good idea regardless.
This is done to move the extension to the new way of structuring JS
modules, and standardize how the main context and goja runtime are
accessed.

For background take a look at grafana/k6@34a7743fb,
grafana/k6#2108, and the "Advanced JavaScript
extension" section in
https://k6.io/docs/misc/k6-extensions/#writing-a-new-extension. The
tldr; is that this structure allows JS extensions to access internal k6
objects, is a saner alternative to `common.Bind()` (which we plan to
deprecate eventually), and has the wanted side effect that each VU gets
a separate instance of the module.
@imiric imiric requested a review from inancgumus November 8, 2021 09:52
@imiric imiric merged commit ab9f81d into main Nov 8, 2021
@imiric imiric deleted the feat/js-modulev2 branch November 8, 2021 12:29
inancgumus pushed a commit that referenced this pull request Nov 9, 2021
Update extension to `ModuleV2`, minor context changes
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.

2 participants