myzhan / locust4j

Locust4j is a load generator for locust, written in Java.
MIT License
81 stars 30 forks source link

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

Closed nitinv0078 closed 4 months ago

nitinv0078 commented 11 months ago

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

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.

myzhan commented 11 months ago

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

nitinv0078 commented 11 months ago

How will first step know which tasks to execute then?

myzhan commented 11 months ago

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.

nitinv0078 commented 11 months ago

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

myzhan commented 11 months ago
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)