How to use reserveVUsForGracefulRampDowns method of executor Package

Best K6 code snippet using executor.reserveVUsForGracefulRampDowns

ramping_vus.go

Source:ramping_vus.go Github

copy

Full Screen

...98//99// It doesn't take into account graceful ramp-downs. It also doesn't deal with100// the end-of-executor drop to 0 VUs, whether graceful or not. These are101// handled by GetExecutionRequirements(), which internally uses this method and102// reserveVUsForGracefulRampDowns().103//104// The zeroEnd argument tells the method if we should artificially add a step105// with 0 VUs at offset sum(stages.duration), i.e. when the executor is106// supposed to end.107//108// It's also important to note how scaling works. Say, we ramp up from 0 to 10109// VUs over 10 seconds and then back to 0, and we want to split the execution in110// 2 equal segments (i.e. execution segments "0:0.5" and "0.5:1"). The original111// execution steps would look something like this:112//113// VUs ^114// 10| *115// 9| ***116// 8| *****117// 7| *******118// 6| *********119// 5| ***********120// 4| *************121// 3| ***************122// 2| *****************123// 1| *******************124// 0------------------------> time(s)125// 01234567890123456789012 (t%10)126// 00000000001111111111222 (t/10)127//128// The chart for one of the execution segments would look like this:129//130// VUs ^131// 5| XXX132// 4| XXXXXXX133// 3| XXXXXXXXXXX134// 2| XXXXXXXXXXXXXXX135// 1| XXXXXXXXXXXXXXXXXXX136// 0------------------------> time(s)137// 01234567890123456789012 (t%10)138// 00000000001111111111222 (t/10)139//140// And the chart for the other execution segment would look like this:141//142// VUs ^143// 5| Y144// 4| YYYYY145// 3| YYYYYYYYY146// 2| YYYYYYYYYYYYY147// 1| YYYYYYYYYYYYYYYYY148// 0------------------------> time(s)149// 01234567890123456789012 (t%10)150// 00000000001111111111222 (t/10)151//152// Notice the time offsets and the slower ramping up and down. All of that is153// because the sum of the two execution segments has to produce exactly the154// original shape, as if the test ran on a single machine:155//156// VUs ^157// 10| Y158// 9| XXX159// 8| YYYYY160// 7| XXXXXXX161// 6| YYYYYYYYY162// 5| XXXXXXXXXXX163// 4| YYYYYYYYYYYYY164// 3| XXXXXXXXXXXXXXX165// 2| YYYYYYYYYYYYYYYYY166// 1| XXXXXXXXXXXXXXXXXXX167// 0------------------------> time(s)168// 01234567890123456789012 (t%10)169// 00000000001111111111222 (t/10)170//171// More information: https://github.com/k6io/k6/issues/997#issuecomment-484416866172func (vlvc RampingVUsConfig) getRawExecutionSteps(et *lib.ExecutionTuple, zeroEnd bool) []lib.ExecutionStep {173 var (174 timeTillEnd time.Duration175 fromVUs = vlvc.StartVUs.Int64176 steps = make([]lib.ExecutionStep, 0, vlvc.precalculateTheRequiredSteps(et, zeroEnd))177 index = lib.NewSegmentedIndex(et)178 )179 // Reserve the scaled StartVUs at the beginning180 scaled, unscaled := index.GoTo(fromVUs)181 steps = append(steps, lib.ExecutionStep{TimeOffset: 0, PlannedVUs: uint64(scaled)})182 addStep := func(timeOffset time.Duration, plannedVUs uint64) {183 if steps[len(steps)-1].PlannedVUs != plannedVUs {184 steps = append(steps, lib.ExecutionStep{TimeOffset: timeOffset, PlannedVUs: plannedVUs})185 }186 }187 for _, stage := range vlvc.Stages {188 stageEndVUs := stage.Target.Int64189 stageDuration := time.Duration(stage.Duration.Duration)190 timeTillEnd += stageDuration191 stageVUDiff := stageEndVUs - fromVUs192 if stageVUDiff == 0 {193 continue194 }195 if stageDuration == 0 {196 scaled, unscaled = index.GoTo(stageEndVUs)197 addStep(timeTillEnd, uint64(scaled))198 fromVUs = stageEndVUs199 continue200 }201 // VU reservation for gracefully ramping down is handled as a202 // separate method: reserveVUsForGracefulRampDowns()203 if unscaled > stageEndVUs { // ramp down204 // here we don't want to emit for the equal to stageEndVUs as it doesn't go below it205 // it will just go to it206 for ; unscaled > stageEndVUs; scaled, unscaled = index.Prev() {207 addStep(208 // this is the time that we should go up 1 if we are ramping up209 // but we are ramping down so we should go 1 down, but because we want to not210 // stop VUs immediately we stop it on the next unscaled VU's time211 timeTillEnd-time.Duration(int64(stageDuration)*(stageEndVUs-unscaled+1)/stageVUDiff),212 uint64(scaled-1),213 )214 }215 } else {216 for ; unscaled <= stageEndVUs; scaled, unscaled = index.Next() {217 addStep(218 timeTillEnd-time.Duration(int64(stageDuration)*(stageEndVUs-unscaled)/stageVUDiff),219 uint64(scaled),220 )221 }222 }223 fromVUs = stageEndVUs224 }225 if zeroEnd && steps[len(steps)-1].PlannedVUs != 0 {226 // If the last PlannedVUs value wasn't 0, add a last step with 0227 steps = append(steps, lib.ExecutionStep{TimeOffset: timeTillEnd, PlannedVUs: 0})228 }229 return steps230}231func absInt64(a int64) int64 {232 if a < 0 {233 return -a234 }235 return a236}237func (vlvc RampingVUsConfig) precalculateTheRequiredSteps(et *lib.ExecutionTuple, zeroEnd bool) int {238 p := et.ScaleInt64(vlvc.StartVUs.Int64)239 var result int64240 result++ // for the first one241 if zeroEnd {242 result++ // for the last one - this one can be more then needed243 }244 for _, stage := range vlvc.Stages {245 stageEndVUs := et.ScaleInt64(stage.Target.Int64)246 if stage.Duration.Duration == 0 {247 result++248 } else {249 result += absInt64(p - stageEndVUs)250 }251 p = stageEndVUs252 }253 return int(result)254}255// If the graceful ramp-downs are enabled, we need to reserve any VUs that may256// potentially have to finish running iterations when we're scaling their number257// down. This would prevent attempts from other executors to use them while the258// iterations are finishing up during their allotted gracefulRampDown periods.259//260// But we also need to be careful to not over-allocate more VUs than we actually261// need. We should never have more PlannedVUs than the max(startVUs,262// stage[n].target), even if we're quickly scaling VUs up and down multiple263// times, one after the other. In those cases, any previously reserved VUs264// finishing up interrupted iterations should be reused by the executor,265// instead of new ones being requested from the execution state.266//267// Here's an example with graceful ramp-down (i.e. "uninterruptible"268// iterations), where stars represent actively scheduled VUs and dots are used269// for VUs that are potentially finishing up iterations:270//271//272// ^273// |274// VUs 6| *..............................275// 5| ***.......*..............................276// 4|*****.....***.....**..............................277// 3|******...*****...***..............................278// 2|*******.*******.****..............................279// 1|***********************..............................280// 0--------------------------------------------------------> time(s)281// 012345678901234567890123456789012345678901234567890123 (t%10)282// 000000000011111111112222222222333333333344444444445555 (t/10)283//284// We start with 4 VUs, scale to 6, scale down to 1, scale up to 5, scale down285// to 1 again, scale up to 4, back to 1, and finally back down to 0. If our286// gracefulStop timeout was 30s (the default), then we'll stay with 6 PlannedVUs287// until t=32 in the test above, and the actual executor could run until t=52.288// See TestRampingVUsConfigExecutionPlanExample() for the above example289// as a unit test.290//291// The algorithm we use below to reserve VUs so that ramping-down VUs can finish292// their last iterations is pretty simple. It just traverses the raw execution293// steps and whenever there's a scaling down of VUs, it prevents the number of294// VUs from decreasing for the configured gracefulRampDown period.295//296// Finishing up the test, i.e. making sure we have a step with 0 VUs at time297// executorEndOffset, is not handled here. Instead GetExecutionRequirements()298// takes care of that. But to make its job easier, this method won't add any299// steps with an offset that's greater or equal to executorEndOffset.300func (vlvc RampingVUsConfig) reserveVUsForGracefulRampDowns( //nolint:funlen301 rawSteps []lib.ExecutionStep, executorEndOffset time.Duration,302) []lib.ExecutionStep {303 rawStepsLen := len(rawSteps)304 gracefulRampDownPeriod := vlvc.GetGracefulRampDown()305 newSteps := []lib.ExecutionStep{}306 lastPlannedVUs := uint64(0)307 lastDownwardSlopeStepNum := 0308 for rawStepNum := 0; rawStepNum < rawStepsLen; rawStepNum++ {309 rawStep := rawSteps[rawStepNum]310 // Add the first step or any step where the number of planned VUs is311 // greater than the ones in the previous step. We don't need to worry312 // about reserving time for ramping-down VUs when the number of planned313 // VUs is growing. That's because the gracefulRampDown period is a fixed314 // value and any timeouts from early steps with fewer VUs will get315 // overshadowed by timeouts from latter steps with more VUs.316 if rawStepNum == 0 || rawStep.PlannedVUs > lastPlannedVUs {317 newSteps = append(newSteps, rawStep)318 lastPlannedVUs = rawStep.PlannedVUs319 continue320 }321 // We simply skip steps with the same number of planned VUs322 if rawStep.PlannedVUs == lastPlannedVUs {323 continue324 }325 // If we're here, we have a downward "slope" - the lastPlannedVUs are326 // more than the current rawStep's planned VUs. We're going to look327 // forward in time (up to gracefulRampDown) and inspect the rawSteps.328 // There are a 3 possibilities:329 // - We find a new step within the gracefulRampDown period which has330 // the same number of VUs or greater than lastPlannedVUs. Which331 // means that we can just advance rawStepNum to that number and we332 // don't need to worry about any of the raw steps in the middle!333 // Both their planned VUs and their gracefulRampDown periods will334 // be lower than what we're going to set from that new rawStep -335 // we've basically found a new upward slope or equal value again.336 // - We reach executorEndOffset, in which case we are done - we can't337 // add any new steps, since those will be after the executor end338 // offset.339 // - We reach the end of the rawSteps, or we don't find any higher or340 // equal steps to prevStep in the next gracefulRampDown period. So341 // we'll simply add a new entry into newSteps with the values342 // {timeOffsetWithTimeout, rawStep.PlannedVUs}, in which343 // timeOffsetWithTimeout = (prevStep.TimeOffset + gracefulRampDown),344 // after which we'll continue with traversing the following rawSteps.345 //346 // In this last case, we can also keep track of the downward slope. We347 // can save the last index we've seen, to optimize future lookaheads by348 // starting them from the furhest downward slope step index we've seen so349 // far. This can be done because the gracefulRampDown is constant, so350 // when we're on a downward slope, raw steps will always fall in the351 // gracefulRampDown "shadow" of their preceding steps on the slope.352 skippedToNewRawStep := false353 timeOffsetWithTimeout := rawStep.TimeOffset + gracefulRampDownPeriod354 advStepStart := rawStepNum + 1355 if lastDownwardSlopeStepNum > advStepStart {356 advStepStart = lastDownwardSlopeStepNum357 }358 wasRampingDown := true359 for advStepNum := advStepStart; advStepNum < rawStepsLen; advStepNum++ {360 advStep := rawSteps[advStepNum]361 if advStep.TimeOffset > timeOffsetWithTimeout {362 break363 }364 if advStep.PlannedVUs >= lastPlannedVUs {365 rawStepNum = advStepNum - 1366 skippedToNewRawStep = true367 break368 }369 if wasRampingDown {370 if rawSteps[advStepNum-1].PlannedVUs > advStep.PlannedVUs {371 // Still ramping down372 lastDownwardSlopeStepNum = advStepNum373 } else {374 // No longer ramping down375 wasRampingDown = false376 }377 }378 }379 // Nothing more to do here, found a new "slope" with equal or grater380 // PlannedVUs in the gracefulRampDownPeriod window, so we go to it.381 if skippedToNewRawStep {382 continue383 }384 // We've reached the absolute executor end offset, and we were already385 // on a downward "slope" (i.e. the previous planned VUs are more than386 // the current planned VUs), so nothing more we can do here.387 if timeOffsetWithTimeout >= executorEndOffset {388 break389 }390 newSteps = append(newSteps, lib.ExecutionStep{391 TimeOffset: timeOffsetWithTimeout,392 PlannedVUs: rawStep.PlannedVUs,393 })394 lastPlannedVUs = rawStep.PlannedVUs395 }396 return newSteps397}398// GetExecutionRequirements very dynamically reserves exactly the number of399// required VUs for this executor at every moment of the test.400//401// If gracefulRampDown is specified, it will also be taken into account, and the402// number of needed VUs to handle that will also be reserved. See the403// documentation of reserveVUsForGracefulRampDowns() for more details.404//405// On the other hand, gracefulStop is handled here. To facilitate it, we'll406// ensure that the last execution step will have 0 VUs and will be at time407// offset (sum(stages.Duration)+gracefulStop). Any steps that would've been408// added after it will be ignored. Thus:409// - gracefulStop can be less than gracefulRampDown and can cut the graceful410// ramp-down periods of the last VUs short.411// - gracefulRampDown can be more than gracefulStop:412// - If the user manually ramped down VUs at the end of the test (i.e. the413// last stage's target is 0), then this will have no effect.414// - If the last stage's target is more than 0, the VUs at the end of the415// executor's life will have more time to finish their last iterations.416func (vlvc RampingVUsConfig) GetExecutionRequirements(et *lib.ExecutionTuple) []lib.ExecutionStep {417 steps := vlvc.getRawExecutionSteps(et, false)418 executorEndOffset := sumStagesDuration(vlvc.Stages) + time.Duration(vlvc.GracefulStop.Duration)419 // Handle graceful ramp-downs, if we have them420 if vlvc.GracefulRampDown.Duration > 0 {421 steps = vlvc.reserveVUsForGracefulRampDowns(steps, executorEndOffset)422 }423 // If the last PlannedVUs value wasn't 0, add a last step with 0424 if steps[len(steps)-1].PlannedVUs != 0 {425 steps = append(steps, lib.ExecutionStep{TimeOffset: executorEndOffset, PlannedVUs: 0})426 }427 return steps428}429// NewExecutor creates a new RampingVUs executor430func (vlvc RampingVUsConfig) NewExecutor(es *lib.ExecutionState, logger *logrus.Entry) (lib.Executor, error) {431 return RampingVUs{432 BaseExecutor: NewBaseExecutor(vlvc, es, logger),433 config: vlvc,434 }, nil435}...

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx, cancel := context.WithCancel(context.Background())4 defer cancel()5 executorConfig := executor.NewConstantArrivalRateConfig()6 executorConfig.TimeUnit = types.NullDurationFrom(10 * time.Millisecond)7 executorConfig.Duration = types.NullDurationFrom(1 * time.Second)8 executor := executor.NewConstantArrivalRate(executorConfig)9 engine, err := lib.NewEngine(ctx, lib.Options{}, nil)10 if err != nil {11 fmt.Println(err)12 }13 runner, err := engine.NewTestRun(ctx, lib.TestRunOptions{14 ExecutionPlan: lib.ExecutionPlan{15 Steps: []lib.ExecutionStep{16 {Executor: executor},17 },18 },19 }, testutils.NewLogger())20 if err != nil {21 fmt.Println(err)22 }23 metricSamples := make(chan stats.SampleContainer, 1000)24 err = runner.Run(ctx, metricSamples)25 if err != nil {26 fmt.Println(err)27 }28 close(metricSamples)29 for metricSample := range metricSamples {30 fmt.Println(metricSample)31 }32}

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 ctx, cancel := context.WithCancel(context.Background())4 defer cancel()5 logger := logrus.StandardLogger()6 logger.SetLevel(logrus.DebugLevel)7 runners := make(map[string]lib.Runner)8 runners["test"] = &lib.TestRunner{}9 runners["js"] = &lib.JSRunner{}10 testRunner := lib.NewTestRunner(runners, 1*time.Second, logger)11 plan := lib.Plan{12 Options: lib.Options{13 MaxVUs: null.IntFrom(10),14 MaxVUsNull: types.NullBoolFrom(true),15 Duration: types.NullDurationFrom(10 * time.Second),16 DurationNull: types.NullBoolFrom(true),17 GracefulStop: types.NullDurationFrom(2 * time.Second),18 GracefulStopNull: types.NullBoolFrom(true),19 Exec: null.StringFrom("test"),20 Throw: null.BoolFrom(false),21 NoSetup: null.BoolFrom(false),22 NoTeardown: null.BoolFrom(false),23 NoConnectionReuse: null.BoolFrom(false),24 NoVUConnectionReuse: null.BoolFrom(false),25 NoUsageReport: null.BoolFrom(false),26 NoColor: null.BoolFrom(false),27 NoThresholds: null.BoolFrom(false),28 NoSummary: null.BoolFrom(false),29 Verbose: null.BoolFrom(false),30 HostsNull: types.NullBoolFrom(true),31 MinIterationDuration: types.NullDurationFrom(0),32 MinIterationDurationNull: types.NullBoolFrom(true),33 IterationTimeout: types.NullDurationFrom(0),34 IterationTimeoutNull: types.NullBoolFrom(true),

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1func TestReserveVUsForGracefulRampDowns(t *testing.T) {2 t.Parallel()3 logHook := &testutils.SimpleLogrusHook{HookedLevels: []logrus.Level{logrus.WarnLevel}}4 log := logrus.New()5 log.AddHook(logHook)6 log.SetOutput(ioutil.Discard)7 log.SetLevel(logrus.DebugLevel)8 testCases := []struct {9 }{10 {11 exec: &Executor{12 config: lib.ExecutorConfig{13 GracefulRampDown: types.NullDurationFrom(0),14 },15 },16 },17 {18 exec: &Executor{19 config: lib.ExecutorConfig{20 GracefulRampDown: types.NullDurationFrom(1 * time.Second),21 },22 },23 },24 }25 for _, tc := range testCases {26 t.Run(tc.name, func(t *testing.T) {27 tc.exec.reserveVUsForGracefulRampDowns(context.Background(), tc.vus)28 assert.Equal(t, tc.vus, tc.exec.vus)29 assert.Equal(t, int64(0), tc.exec.gracefulRampDownVUs)30 assert.Equal(t, tc.vus, tc.exec.vusMax)31 assert.Equal(t, tc.vus, tc.exec.vusMaxInitialized)32 })33 }34}35func TestRun(t *testing.T) {36 t.Parallel()37 testCases := []struct {38 }{39 {40 exec: &Executor{41 config: lib.ExecutorConfig{42 GracefulRampDown: types.NullDurationFrom(0),43 },44 },45 },46 {47 exec: &Executor{48 config: lib.ExecutorConfig{49 GracefulRampDown: types.NullDurationFrom(1 * time.Second),50 },51 },52 },53 }54 for _, tc := range testCases {55 t.Run(tc.name, func(t

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1func ( executor * Executor ) reserveVUsForGracefulRampDowns ( ) { 2 for i := 0 ; i < len ( executor . gracefulRampDowns ) ; i ++ { 3 executor . gracefulRampDowns [ i ] . ReserveVUs ( ) 4 } 5 }6func ( executor * Executor ) getPlannedVUs ( ) int64 { 7 plannedVUs := int64 ( 0 ) 8 for i := 0 ; i < len ( executor . gracefulRampDowns ) ; i ++ { 9 plannedVUs += executor . gracefulRampDowns [ i ] . GetPlannedVUs ( ) 10 } 11 }12func ( executor * Executor ) getCurrentlyActiveVUs ( ) int64 { 13 activeVUs := int64 ( 0 ) 14 for i := 0 ; i < len ( executor . gracefulRampDowns ) ; i ++ { 15 activeVUs += executor . gracefulRampDowns [ i ] . GetCurrentlyActiveVUs ( ) 16 } 17 }18func ( executor * Executor ) getFullIterationCount ( ) int64 { 19 fullIterationCount := int64 ( 0 ) 20 for i := 0 ; i < len ( executor . gracefulRampDowns ) ; i ++ { 21 fullIterationCount += executor . gracefulRampDowns [ i ] . GetFullIterationCount ( ) 22 } 23 }24func ( executor * Executor ) getInitializedVUs ( )

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1func (e *Executor) reserveVUsForGracefulRampDowns() {2 for _, step := range e.executionScheduler.GetExecutionState().GetFullExecutionSteps() {3 if step.IsGracefulRampDown() {4 gracefulRampDowns = append(gracefulRampDowns, step)5 }6 }7 e.logger.Debug("Reserving VUs for graceful ramp-downs", gracefulRampDowns)8 e.vuHandleMx.Lock()9 defer e.vuHandleMx.Unlock()10 for _, step := range gracefulRampDowns {11 e.vuHandles[step.GetTimeOffset()] = make([]*vuHandle, step.GetPlannedVUs())12 }13}14func (e *Executor) reserveVUsForGracefulRampDowns() {15 for _, step := range e.executionScheduler.GetExecutionState().GetFullExecutionSteps() {16 if step.IsGracefulRampDown() {17 gracefulRampDowns = append(gracefulRampDowns, step)18 }19 }20 e.logger.Debug("Reserving VUs for graceful ramp-downs", gracefulRampDowns)21 e.vuHandleMx.Lock()22 defer e.vuHandleMx.Unlock()23 for _, step := range gracefulRampDowns {24 e.vuHandles[step.GetTimeOffset()] = make([]*vuHandle, step.GetPlannedVUs())25 }26}27func (e *Executor) reserveVUsForGracefulRampDowns() {28 for _, step := range e.executionScheduler.GetExecutionState().GetFullExecutionSteps() {29 if step.IsGracefulRampDown() {30 gracefulRampDowns = append(gracefulRampDowns, step)31 }32 }33 e.logger.Debug("Reserving VUs for graceful ramp-downs", gracefulRampDowns)34 e.vuHandleMx.Lock()35 defer e.vuHandleMx.Unlock()

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1func (e *Executor) reserveVUsForGracefulRampDowns() {2 var (3 ctx, cancel = context.WithCancel(context.Background())4 defer cancel()5 for i := 0; i < e.config.GracefulRampDown; i++ {6 vu, err := e.newVU(ctx, &sync.WaitGroup{})7 if err != nil {8 e.logger.WithError(err).Error("Error while creating a VU")9 }10 vu.RunOnce(ctx)11 wg.Add(1)12 go func() {13 defer wg.Done()14 vu.RunOnce(ctx)15 }()16 }17 wg.Wait()18 e.logger.Debug("Finished graceful ramp down")19}20func (e *Executor) reserveVUsForGracefulRampDowns() {21 var (22 ctx, cancel = context.WithCancel(context.Background())23 defer cancel()24 for i := 0; i < e.config.GracefulRampDown; i++ {25 vu, err := e.newVU(ctx, &sync.WaitGroup{})26 if err != nil {27 e.logger.WithError(err).Error("Error while creating a VU")28 }29 vu.RunOnce(ctx)30 wg.Add(1)31 go func() {32 defer wg.Done()33 vu.RunOnce(ctx)34 }()35 }36 wg.Wait()37 e.logger.Debug("Finished graceful ramp down")38}39func (e *Executor) reserveVUsForGracefulRampDowns() {40 var (41 ctx, cancel = context.WithCancel(context.Background())42 defer cancel()43 for i := 0; i < e.config.GracefulRampDown; i++ {44 vu, err := e.newVU(ctx, &sync.WaitGroup{})45 if err != nil {46 e.logger.WithError(err).Error("Error while creating a VU")47 }48 vu.RunOnce(ctx)49 wg.Add(1)50 go func() {51 defer wg.Done()

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1func reserveVUsForGracefulRampDowns(ctx context.Context, executor *Executor, vuHandles []lib.InitializedVU, vuCount int64) ([]lib.InitializedVU, error) {2 if vuCount == 0 {3 }4 for _, vu := range vus {5 if err := executor.gracefulRampDownVUs.Remove(vu); err != nil {6 }7 }8}9func (e *Executor) gracefulRampDownVUs(ctx context.Context, vu lib.InitializedVU) {10 if e.config.GracefulStop.Enabled.Bool {11 e.gracefulRampDownVUs.Add(vu)12 }13}14func (g *gracefulRampDownVUs) Add(vu lib.InitializedVU) {15 g.mu.Lock()16 defer g.mu.Unlock()17 g.vus[vu] = struct{}{}18}19func (g *gracefulRampDownVUs) vus() []lib.InitializedVU {20 g.mu.Lock()21 defer g.mu.Unlock()22 vus := make([]lib.InitializedVU, 0, len(g.vus))23 for vu := range g.vus {24 vus = append(vus, vu)25 }26}27func (g *gracefulRampDownVUs) Remove(vu lib.InitializedVU) error {28 g.mu.Lock()29 defer g.mu.Unlock()30 if _, ok := g.vus[vu]; !ok {31 return errors.New("VU not found in gracefulRampDownVUs")32 }33 delete(g.vus, vu)34}35func (g *gracefulRampDownVUs) vus() []lib.InitializedVU {

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1func main() {2 executor := new(executor)3 executor.Init()4 executor.reserveVUsForGracefulRampDowns()5 executor.reserveVUsForGracefulRampDowns()6 executor.reserveVUsForGracefulRampDowns()7}8func main() {9 executor := new(executor)10 executor.Init()11 executor.reserveVUsForGracefulRampDowns()12 executor.reserveVUsForGracefulRampDowns()13 executor.reserveVUsForGracefulRampDowns()14}15func main() {16 executor := new(executor)17 executor.Init()18 executor.reserveVUsForGracefulRampDowns()19 executor.reserveVUsForGracefulRampDowns()20 executor.reserveVUsForGracefulRampDowns()21}22func main() {23 executor := new(executor)24 executor.Init()25 executor.reserveVUsForGracefulRampDowns()26 executor.reserveVUsForGracefulRampDowns()27 executor.reserveVUsForGracefulRampDowns()28}

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1import (2type Executor struct {3 gracefulRampDownVUs map[*vuHandle]struct{}4}5type vuHandle struct {6}7type VU struct {8}9func main() {10 executor.gracefulRampDownVUs = make(map[*vuHandle]struct{})11 executor.gracefulRampDownVUs[&vuHandle] = struct{}{}12 executor.reserveVUsForGracefulRampDowns(1)13}14func (e *Executor) reserveVUsForGracefulRampDowns(n int64) {15 fmt.Println("Reserve VUs for graceful ramp down")16 for vuHandle := range e.gracefulRampDownVUs {17 if n == 0 {18 }19 if vuHandle.VU.id == 1 {20 fmt.Println("VU ID: ", vuHandle.VU.id)21 delete(e.gracefulRampDownVUs, vuHandle)22 }23 }24}25import (26type Executor struct {27 gracefulRampDownVUs map[*vuHandle]struct{}28}29type vuHandle struct {30}31type VU struct {32}33func main() {34 executor.gracefulRampDownVUs = make(map[*vuHandle]struct{})

Full Screen

Full Screen

reserveVUsForGracefulRampDowns

Using AI Code Generation

copy

Full Screen

1func (executor *Executor) reserveVUsForGracefulRampDowns() {2 if executor.config.GracefulRampDown > 0 {3 if executor.config.GracefulRampDown.Valid {4 } else {5 gracefulRampDownDuration = executor.config.GetExecutionRequirements(executor.executionState).GetMaxDuration()6 }7 executor.executionState.GracefulRampDownMaxVUs = executor.executionState.GetCurrentlyActiveVUsCount()8 }9}10func (executor *Executor) getVU() (lib.InitializedVU, error) {11 if executor.executionState.GracefulRampDownDuration > 0 {12 if !executor.executionState.GracefulRampDownInitialized {13 executor.reserveVUsForGracefulRampDowns()14 }15 if executor.executionState.GracefulRampDownMaxVUs > 0 {16 return executor.executionState.GetPlannedVU(executor.logger, true)17 }18 }19 return executor.executionState.GetPlannedVU(executor.logger, false)20}21func (executor *Executor) returnVU(vu lib.InitializedVU, wasReused bool) {22 executor.executionState.ReturnVU(vu, wasReused)23}24func (executor *Executor) getIterationCount() (int64, error) {25 nullCount := int64(0)26 if executor.config.Iterations.Valid {27 }28 if executor.config.Time.Valid {29 }30 if executor.config.Duration.Valid {31 }32}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run K6 automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Most used method in

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful