-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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 k6/http
and k6/html
to the new JS Module
API
#2226
Conversation
1c8ddda
to
d4ea55c
Compare
k6/http
to ModuleV2
k6/http
and k6/html
to the new JS Module
API
k6/http
and k6/html
to the new JS Module
APIk6/http
and k6/html
to the new JS Module
API
I'll fix the linter errors and squash the commits later, but the code should be reasonably ready for review now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM just some small suggestions, not too enthusiastic about the ModuleInstance
<-> Client
cycle dependency but I think we can't do better for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍 A couple of nitpicks that you should feel free to ignore.
A general remark about a pattern I've observed in other places in the code: I often see private and public functions/methods/types appearing in a seamingly unordered fashion. I was always told, and exposed to the idea that especially in Go (as naming has an impact on the privateness/publicness of the code), it's important to have types/functions/methods appear in order of importance: public first, then private. Most essential/important first, less important/implementation details last. In my experience, being intentional about it makes a codebase much easier to understand, navigate and maintain.
What do you folks think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM in general, I left some comments I do think we should discuss what we want to do with Exports more in general soon so that we can align all internal modules within this release
js/modules/k6/http/http.go
Outdated
func (mi *ModuleInstance) Exports() modules.Exports { | ||
return modules.Exports{ | ||
Default: mi.exports, | ||
// TODO: add new HTTP APIs like Client, Request, etc. as named exports? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see #2258 as it was more or less written for this module 🤣
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started by reading that issue, but I am still not sure exactly what you mean, sorry 😞 Do you mean I should just return everything as named exports here and rely on this?
Lines 180 to 182 in 5c14dae
if exp.Default == nil { | |
return exp.Named | |
} |
mustAddProp := func(name, val string) { | ||
err := mi.exports.DefineDataProperty( | ||
name, rt.ToValue(val), goja.FLAG_FALSE, goja.FLAG_FALSE, goja.FLAG_TRUE, | ||
) | ||
if err != nil { | ||
common.Throw(rt, err) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this is the one use case for using goja.Object
as the exports - being able to make things not act just as a simple map, as in this case not being able to overwrite this constants.
The question is should you not be able to overwrite this but be able to overwrite the functions ?
Should we return something different that is more robust in handling such cases
See #2241 (comment) (And above comments) for discussion on why I prefer map[string]interface{}
for most cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm 🤔 I can understand the map[string]interface{}
preference, but goja will just convert that to an Object
anyway. And I like being able to have constants be constant 😅
Do you know hot this should work with proper ES modules? If you have export const something
, does that actually make it constant in the code that imports it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you have export const something, does that actually make it constant in the code that imports it?
yes
c6da5bc
to
d87b4d6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the effort in doing it, I mostly omitted to comment the parts related to the exports
because I would wait for updates from @mstoykov experiments before providing any input there.
The rest is mostly asking for clarifications about TODOs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM apart from the tests changes. I would expect that there will be some trouble with the tests either way so 🤷
f072e4d
to
18919f3
Compare
18919f3
to
8a475ab
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just one missing change, the rest LGTM
8a475ab
to
2d45769
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM (ofc with green CI), thanks for doing it 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just went through the PR again. Realized I forgot to approve it in the first place. Sorry for that 🙏🏻 Great work 🤝 🎉
2d45769
to
7b34a8d
Compare
I thought I needed to refactor both
k6/html
andk6/http
together, since the latter depends on the former, but turns out that wasn't quite the case and the panic was caused by something else... 😅 Still, it doesn't hurt and thek6/html
changes are relatively minor...I like how this looks like for now, and I'll probably make another PR after this to move some things out of the
js.Runner.newVu()
andlib.State
and into thek6/http
module, for example:TLSConfig
,Transport
andCookieJar
probably should go in theClient
and be initialized in a constructor, which will use the globallib.Options
as the default options for its initializationBPool
can either be in theClient
orModuleInstance
, dependsRPSLimit
should probably be in theRootModule
As a prerequisite to these though, other built-in modules (and xk6 extensions) should be able to essentially do the equivalent of
require('k6/http')
internally, i.e. get theModuleInstance
for their VU. And to do that without Go import loops, we probably have to move some of the logic fromjs/InitContext
tojs/common.InitEnvironment