locust4j icon indicating copy to clipboard operation
locust4j copied to clipboard

Run locust using a schedule from yaml file and RampUpRateLimiter not working as expected

Open nitinv0078 opened this issue 2 years ago • 5 comments

yaml file being read into locustConfig: uiMaxRPS: 20 autoRun: true steps:

  • numUsers: 10 hatchRate: 1 durationInSec: 30 maxRPS: 20 name: Initial Load
  • numUsers: 15 hatchRate: 2 durationInSec: 60 maxRPS: 30 name: Ramp up
  • numUsers: 20 hatchRate: 3 durationInSec: 90 maxRPS: 40 name: Peak Load

DurationInSec - indicates how long should the step be run in seconds NumUsers - indicates the maximum number of users to spawn HatchRate - indicates how fast each user can be spawn per second MaxRPS - indicates max RPS for the step Name - a label to show which step the schedule is running

I am trying to implement a scenario where if autoRun is true then the run of locust is automatic based on the details from Step in yaml config file and if possible the run is visible on the locust web UI or at least I still get the statistics report in a presentable form .

When autoRun is false then the user gets to control the NumUsers and HatchRate from Locust Web UI. The false flow is working very well but for autoRun true neither the task execution is happening as expected nor I see anything on locust web UI nor the execution stops after steps completion.

Below is code I used:

 if (locustConfig.getAutoRun()) {
            for (LocustConfig.Step step : locustConfig.getSteps()) {
                System.out.println("Executing step : "+ step.getName() + "\n MaxRPS: " +step.getMaxRPS()+ "\n HatchRate: " +step.getHatchRate()+ "\n Duration: " +step.getDurationInSec());
                locust.setRateLimiter(new RampUpRateLimiter(step.getMaxRPS(), step.getNumUsers(), step.getHatchRate(), TimeUnit.SECONDS, step.getDurationInSec(), TimeUnit.SECONDS));
                tasks.clear();
                tasks.add(new GetHandshakeApiTask(1, getHandshakeApi));
                tasks.add(new GetValidateUserLicenseApiTask(1, getValidateUserLicenseApi));
                locust.run(tasks);
                
            }
        }  else {
            locust.setMaxRPS(locustConfig.getUiMaxRPS());
            tasks.add(new GetHandshakeApiTask(1, getHandshakeApi));
            tasks.add(new GetValidateUserLicenseApiTask(1, getValidateUserLicenseApi));
    
            locust.run(tasks);
        }
        
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            locust.stop();
            Stats.getInstance().stop();
         }));
        
    }
}

Please help me with this implementation.

nitinv0078 avatar Oct 04 '23 09:10 nitinv0078

Because locust.run will block, so only the first step works.

myzhan avatar Oct 07 '23 02:10 myzhan

How will first step know which tasks to execute then?

nitinv0078 avatar Oct 07 '23 02:10 nitinv0078

I think you can refer to taskset to control multiple tasks, and implement your own taskset, and the taskset can change the ratelimiter at runtime.

myzhan avatar Oct 07 '23 06:10 myzhan

I tried multiple ways but nothing gave the desired outcome. Can you explain bit more. My understanding is even task set needs to be run via locust

nitinv0078 avatar Oct 07 '23 06:10 nitinv0078

AbstractTaskSet taskset = new TaskSetThatSupportSteps()

// create a timer in another thread
timer.run(
      for (LocustConfig.Step step : locustConfig.getSteps()) {
             locust.SetRateLimiter(xxxx);
             taskset.clear()
             taskset.add(other tasks)
      }
)

locust.run(taskset)

myzhan avatar Oct 07 '23 07:10 myzhan