-
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
Core changes for k6/x/execution
JS module
#1863
Conversation
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.
Haven't taken a deeper look or tried the code, but some comments:
- IMO we should allow getting the info in all cases where any info is available
- The things that call functions should probably call the functions on the spot (without any caching) or be functions in the first place
- Given that a lot of the
*State
objects seem "static" can we have 1 of those and just give it everywhere - given
3.
(and even without it) can you check and make certain that a user script can't change any of the values?
Are you referring to being able to call this from init? Most of this information doesn't make sense outside the context of a running VU/scenario. Only
Hhmm I'm not sure I prefer the API to be something like I could give it a shot if you feel strongly about it, though would prefer the
Hhmm you mean about But Ah, no, you're referring about the
Sure. With dumb / already evaluated objects this shouldn't matter, but I'll confirm after your suggested changes. |
I have only skimmed the code changes, so I haven't fully grokked the PR yet, but I have a more generic comment here. I think the MVP version of #1320 shouldn't be exposing information users can already mostly get. It should be exposing things that they cannot currently get in any way. Primarily because it would require some refactoring to the executors and may change how the rest of the feature is implemented. From what I can see, I think the MVP of this feature should have these two/three pieces of information, with everything else being a nice-to-have bonus:
The first 2 are the equivalent of |
@na-- OK, so to clarify, that would involve adding a few additional executor-specific counters, right? Except for the last global across instances values which could be calculated given the execution segment? |
Yeah, basically a local VU number for the scenario (basically immutable after the VU activation in the scenario) and a local iteration number for the specific VU in the scenario (mutable, but the only lock contention here would be between whatever increments it and this new |
eed870f
to
555e1eb
Compare
Codecov Report
@@ Coverage Diff @@
## master #1863 +/- ##
==========================================
+ Coverage 71.50% 71.70% +0.20%
==========================================
Files 180 181 +1
Lines 13969 14008 +39
==========================================
+ Hits 9988 10045 +57
+ Misses 3344 3327 -17
+ Partials 637 636 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
555e1eb
to
4be00f3
Compare
So it's unfortunately safe to say that this won't make the v0.31.0 release. 😞 I think the functionality described here is implemented now, but it will need thorough testing and actually making the tests pass consistently. Please give the code an overview, the commits should be fairly isolated, and test it on your machine to ensure it's at least functionally OK. What's pending:
|
lib/executor/helpers.go
Outdated
@@ -108,6 +108,7 @@ func getIterationRunner( | |||
|
|||
// TODO: move emission of end-of-iteration metrics here? | |||
executionState.AddFullIterations(1) | |||
incrIter() |
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.
We're currently only tracking completed/full iterations. Would tracking interrupted iterations too be interesting to users? It would essentially double the amount of counters for everything... :-/
4be00f3
to
69d1150
Compare
7d41b47
to
34a0596
Compare
Codecov Report
@@ Coverage Diff @@
## master #1863 +/- ##
==========================================
+ Coverage 71.99% 72.17% +0.17%
==========================================
Files 181 181
Lines 14149 14283 +134
==========================================
+ Hits 10187 10309 +122
- Misses 3338 3348 +10
- Partials 624 626 +2
Flags with carried forward coverage won't be shown. Click here to find out more.
Continue to review full report at Codecov.
|
34a0596
to
923f494
Compare
@mstoykov @na-- Could you take another look and let me know if there's anything pending here? From what we discussed, allowing the use of this module in the init context is the major thing still missing. After taking another look, I still think it would require substantial refactoring to achieve, and most of the information just doesn't make sense in the init context. The big (only?) use case that does make sense is retrieving the max test duration before the test starts, as mentioned on the forum and here. The problem with this is that the init context is evaluated before the A possible approach would be to offer a pure JS API to calculate and return just the max duration, but that would duplicate a lot of the same logic we have in Go, and it doesn't seem worth it considering it can be done with the current implementation from the |
* Use a single segmented index for local and global iterations This removes the need for a lot of the additional synchronization. This also makes it so there are global iterations for all executors. For some of those it means that the global iteration will be *unique* among instances but doesn't necessary mean that iterations with smaller numbers *have* run or *will* run in the same test run. This is somewhat like how it is for the executors for which we already had it, there is nothing making certain that a shared-iterations executor will not run out of time to run all the iterations on one of the instances or a arrival-rate to not have to drop iterations due to lack VUs to execute them. * Update lib/executor/base_executor.go Co-authored-by: Ivan Mirić <[email protected]> * unexport and comment nextIterationCounters * Remove synchronization in SegmetnedIndex * Drop SegmentedIndexResult * Fix race in TestSharedIterationsGlobalIters There is nothing stopping 5 VUs starting a shared iterations at the same time and one of them getting "slower" to the actual execution than it's iteration counter suggests. Co-authored-by: Ivan Mirić <[email protected]>
Resolves #1863 (comment)
Calling these methods defined on a value receiver copies the BaseExecutor instance and could cause a data race if another goroutine is writing to it. In practice this wasn't a problem and unlikely anyone would ever run into it on master, but it did appear on the feat/1320-execution-api branch (#1863) when running: go run -race main.go run --quiet -u 5 -i 5 'github.com/k6io/k6/samples/http_get.js' Clipped stack trace: WARNING: DATA RACE Write at 0x00c00050d7a8 by main goroutine: go.k6.io/k6/lib/executor.(*SharedIterations).Init() /home/ivan/Projects/k6io/k6/lib/executor/shared_iterations.go:179 +0x384 go.k6.io/k6/core/local.(*ExecutionScheduler).Init() /home/ivan/Projects/k6io/k6/core/local/local.go:276 +0xc1c go.k6.io/k6/core.(*Engine).Init() /home/ivan/Projects/k6io/k6/core/engine.go:190 +0x148 go.k6.io/k6/cmd.getRunCmd.func1() /home/ivan/Projects/k6io/k6/cmd/run.go:248 +0x1ad7 ... Previous read at 0x00c00050d7a8 by goroutine 32: go.k6.io/k6/lib/executor.(*SharedIterations).GetProgress() <autogenerated>:1 +0x85 go.k6.io/k6/cmd.getRunCmd.func1.1() /home/ivan/Projects/k6io/k6/cmd/run.go:180 +0x13d Also see #1863 (comment) .
We might want to eventually add this back once we determine the usefulness of it, possibly with a global (across instances) variant. Resolves #1863 (comment)
739bb55
to
0279c67
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.
k6/x/execution
JS 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.
LGTM 👏
Some copying and renaming required, but it's not bad.
Some copying and renaming required, but it's not bad.
Based on internal design discussion. Access by property is more idiomatic for JS. Also, s/stats/info/ based on feedback in grafana/k6#1863.
Based on internal design discussion. Access by property is more idiomatic for JS. Also, s/stats/info/ based on feedback in grafana/k6#1863.
Based on internal design discussion. Access by property is more idiomatic for JS. Also, s/stats/info/ based on feedback in grafana/k6#1863.
Based on internal design discussion. Access by property is more idiomatic for JS. Also, s/stats/info/ based on feedback in grafana/k6#1863.
This moves the iteration state from lib.State to js.VU and js.ActiveVU, and adds synchronization between scenario iteration increments to ensure the information returned by k6/execution within a single VU iteration is stable. Resolves grafana/k6#1863 (comment)
Calling these methods defined on a value receiver copies the BaseExecutor instance and could cause a data race if another goroutine is writing to it. In practice this wasn't a problem and unlikely anyone would ever run into it on master, but it did appear on the feat/1320-execution-api branch (#1863) when running: go run -race main.go run --quiet -u 5 -i 5 'github.com/k6io/k6/samples/http_get.js' Clipped stack trace: WARNING: DATA RACE Write at 0x00c00050d7a8 by main goroutine: go.k6.io/k6/lib/executor.(*SharedIterations).Init() /home/ivan/Projects/k6io/k6/lib/executor/shared_iterations.go:179 +0x384 go.k6.io/k6/core/local.(*ExecutionScheduler).Init() /home/ivan/Projects/k6io/k6/core/local/local.go:276 +0xc1c go.k6.io/k6/core.(*Engine).Init() /home/ivan/Projects/k6io/k6/core/engine.go:190 +0x148 go.k6.io/k6/cmd.getRunCmd.func1() /home/ivan/Projects/k6io/k6/cmd/run.go:248 +0x1ad7 ... Previous read at 0x00c00050d7a8 by goroutine 32: go.k6.io/k6/lib/executor.(*SharedIterations).GetProgress() <autogenerated>:1 +0x85 go.k6.io/k6/cmd.getRunCmd.func1.1() /home/ivan/Projects/k6io/k6/cmd/run.go:180 +0x13d Also see grafana/k6#1863 (comment) .
We might want to eventually add this back once we determine the usefulness of it, possibly with a global (across instances) variant. Resolves grafana/k6#1863 (comment)
These are core changes needed for the
k6/x/execution
JS module.Initially the module was part of core as well, but we decided to extract it into an extension to be able to quickly iterate on the API. See the JS usage and example in the extension repo.
This also inadvertently fixes the segmentation of iterations for the
ramping-arrival-rate
executor. See #1863 (comment).Part of #1320