# swarm **Repository Path**: nihaixia/swarm ## Basic Information - **Project Name**: swarm - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-06-14 - **Last Updated**: 2025-06-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Swarm ============= *An elegant Java client for Locust* ![](docs/images/swarm.png) #### 1. Motivation IMHO, [Locust4j](https://github.com/myzhan/locust4j) a basic implementation for Locust clients written in Java. It has so many restrictions, including: - The code base is not organized well - Not so performant with blocking queues - `AbstractTask` does NOT support async operations - Slow start-up time (mostly by `Utils.getNodeID()`) - Insufficient usage of threading. `Locust4j` will use `N` threads to stimulate `N` users. A big `N` will result in performance degradation (due to context switching of threads) - Not well-supported for async operations Based on implementation of `Locust4j`, `Swarm` is completely re-written to address all issues above, with some additional features: - Auto detect connection status to Locust master hosts and reponse back. - A better model to stimulate concurrent users (with disruptors) #### 2. Implementation - `LMAX Disruptor` for non-blocking queues - `Google Guava` for rate limiting - `Jeromq` + `MessagePack` for working with Locust masters #### 3. Installation Before using `Swarm`, you must declare it as a dependency of your Maven project. For example: ``` com.bigsonata.swarm locust-swarm 1.1.6 ``` You also have to add following dependencies: ``` ch.qos.logback logback-classic 1.2.3 ch.qos.logback logback-core 1.2.3 org.msgpack msgpack-core 0.8.13 org.zeromq jeromq 0.4.3 com.lmax disruptor 3.3.7 com.google.guava guava 23.0 ``` #### 4. How to write your benchmarks ##### 4.1 Overview `Swarm` uses the term of `Cron` to refer to repeating tasks defined by you. Life cycle of a Cron-based instance can be described in the following diagram: ![](docs/images/cron-state.png) `Swarm` is responsible for cloning, initializing crons. ##### 4.2 Cron anatomy ```java // Here is an abridged version of class Cron public abstract class Cron implements Cloneable, Runnable { public Cron(Props props) { this.props = props; } public abstract void process(); public abstract Cron clone(); public void recordFailure(long responseTime, String error) { // .. } public void recordSuccess(long responseTime, long contentLength) { // .. } public void recordSuccess(long responseTime) { // .. } @Override public void run() { // ... process(); } public abstract void dispose(); public abstract void initialize(); } ``` Each cron has its own `props` which defines type & name (to display on the Web interface): ![](docs/images/locust.png) ```java public class Props { protected String type = "default"; protected String name = "cron"; protected int weight = 1; protected boolean async = false; public static Props create() { return new Props(); } public static Props createAsync() { return new Props() .setAsync(true); } public Props setType(String type) { // .. } public Props setName(String name) { // .. } public Props setWeight(int weight) { // .. } public Props setAsync(boolean async) { // .. } } ``` `NOTE:` A cron must specify how it works: synchronously or asynchronously Inside each cron, there are 4 must-overridden methods - `clone`: you should let `Swarm` know how to clone your Cron :D - `initialize` : It's a great place for you to initiate connections (if you want to use pooling mechanism) - `process`: which is repeatedly executed to perform your tests and report results - `dispose`: Swarm will invoke this method to dispose any resources allocated by crons ##### 4.3 Define your crons You need to define your loading test by deriving class `Cron`: For example, in our `AsyncCron`: ```java public class TimerCron extends Cron { public TimerCron() { super(Props.create().setName("timer").setAsync(false)); } @Override public void process() { try { System.out.println("> Processing..."); long start = System.currentTimeMillis(); Thread.sleep(1000); long duration = System.currentTimeMillis() - start; recordSuccess(duration); } catch (InterruptedException e) { e.printStackTrace(); } } @Override public Cron clone() { return new TimerCron(); } @Override public void dispose() { } @Override public void initialize() { } } ``` ##### 4.4 Finalize After defining your crons, finally you need to instruct `Swarm` to start: ```java Locust.Builder.newInstance() .setMasterHost(masterHost) .setMasterPort(masterPort) // Optionally set the interval (in ms) to report statistics // Default: 2000 .setStatInterval(2000) // Optionally set a seed number to generate nodeId .setRandomSeed(0) // Optionally set the number of threads to stimulate Crons // Default: 8 .setThreads(8) // Optionally set the number of maximum requests per second .setMaxRps(1000) // Register cron tasks .setCrons(new TimerCron()); .build() ``` #### 5. Tips - To effectively benchmark with Locust, we may need to use `connection pooling` - See the demo in `src/main/java/com.bigsonata/example` #### 6. Contributions If you find anything wrong or would like to contribute in any way, feel free to create a pull request/open an issue/send me a message. Any comments are welcome! #### 7. History **v1.1.6** - Released in 26/03/2023 - Fixed a compatibility issue with Locust 2.x. Thank you [jayudey-wf](https://github.com/jayudey-wf) for his [PR](https://github.com/anhldbk/swarm/pull/27) **v1.1.5** - Released in 22/10/2021 - Fixed a compatibility issue with Locust on recoding `Occurrences` (with this [PR](https://github.com/anhldbk/swarm/pull/25)) **v1.1.4** - Released in 30/05/2020 - Fixed a compatibility issue with Locust v0.14.6 (reported [here](https://github.com/anhldbk/swarm/issues/19)) **v1.1.3** - Released in 26/02/2020 - Fixed a compatibility issue with Locust v0.14.4. Thank you [gungjodi](https://github.com/gungjodi) for his [PR](https://github.com/anhldbk/swarm/pull/12) **v1.1.0** - Released in 29/12/2019 - Fixed a compatibility issue wit Locust with version > v0.10.0. Thank you [BogdanLivadariu](https://github.com/BogdanLivadariu) for suggesting solutions. - Locust Builder to include `setCrons` - Refactored code & documentation **v1.0.1** - Released in 10/10/2018 - Increased the internal buffer size to 32k (which effectively affect our Crons' througput) **v1.0.0** - Released in 13/08/2018 - Simplified APIs - Used a better mechanism for scheduling crons. This mechanism effectively stimulates hatching users gradually **v0.1.2** - Released in 27/06/2018 - Fixed a bug in processing hatch rates (PR by [@HughZurname](https://github.com/HughZurname)) - Allowed Locust to specify the maximum requests per second (PR by [@jaymoid](https://github.com/jaymoid)) **v0.1.0** - Released in 26/05/2018 - Initial release