diff --git a/src/main/java/io/fusionauth/load/Foreman.java b/src/main/java/io/fusionauth/load/Foreman.java index 39c4d09..b18bd67 100644 --- a/src/main/java/io/fusionauth/load/Foreman.java +++ b/src/main/java/io/fusionauth/load/Foreman.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2022, FusionAuth, All Rights Reserved + * Copyright (c) 2012-2025, FusionAuth, All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,55 +47,51 @@ public class Foreman implements Buildable { public Foreman execute() throws InterruptedException { initialize(); - ExecutorService pool = Executors.newFixedThreadPool(workers.size()); - - // Gradually build up workers, to reduce the chance of failures while we get going. - for (Worker worker : workers) { - WorkerExecutor executor = new WorkerExecutor(worker, loopCount, listeners); - pool.execute(executor); - try { - Thread.sleep(1123); - } catch (Exception ignore) { + try (ExecutorService pool = Executors.newVirtualThreadPerTaskExecutor()) { + + // Gradually build up workers, to reduce the chance of failures while we get going. + for (Worker worker : workers) { + WorkerExecutor executor = new WorkerExecutor(worker, loopCount, listeners); + pool.execute(executor); } - } - if (this.reporter != null) { - this.reporter.schedule(); - } + if (this.reporter != null) { + this.reporter.schedule(); + } - pool.shutdown(); - pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); + pool.shutdown(); + pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); - listeners.forEach(SampleListener::done); + listeners.forEach(SampleListener::done); - if (reporter != null) { - reporter.report(); - } + if (reporter != null) { + reporter.report(); + } - if (reporter != null) { - reporter.stop(); - } + if (reporter != null) { + reporter.stop(); + } + // Temp hack to get some general timings on the OAuth2 Authorize worker broken down by component + if (workers.get(0) instanceof FusionAuthOAuth2AuthorizeWorker) { + System.out.println("\n\n"); + long total = FusionAuthOAuth2AuthorizeWorker.timing.render + FusionAuthOAuth2AuthorizeWorker.timing.post + FusionAuthOAuth2AuthorizeWorker.timing.token; + long iterationCount = (long) workers.size() * loopCount; - // Temp hack to get some general timings on the OAuth2 Authorize worker broken down by component - if (workers.get(0) instanceof FusionAuthOAuth2AuthorizeWorker) { - System.out.println("\n\n"); - long total = FusionAuthOAuth2AuthorizeWorker.timing.render + FusionAuthOAuth2AuthorizeWorker.timing.post + FusionAuthOAuth2AuthorizeWorker.timing.token; - long iterationCount = (long) workers.size() * loopCount; + int renderPercent = (int) (FusionAuthOAuth2AuthorizeWorker.timing.render * 100.0 / total + 0.5); + int postPercent = (int) (FusionAuthOAuth2AuthorizeWorker.timing.post * 100.0 / total + 0.5); + int tokenPercent = (int) (FusionAuthOAuth2AuthorizeWorker.timing.token * 100.0 / total + 0.5); - int renderPercent = (int) (FusionAuthOAuth2AuthorizeWorker.timing.render * 100.0 / total + 0.5); - int postPercent = (int) (FusionAuthOAuth2AuthorizeWorker.timing.post * 100.0 / total + 0.5); - int tokenPercent = (int) (FusionAuthOAuth2AuthorizeWorker.timing.token * 100.0 / total + 0.5); + System.out.println("Render: " + FusionAuthOAuth2AuthorizeWorker.timing.render + " ms, Average: " + FusionAuthOAuth2AuthorizeWorker.timing.render / (iterationCount) + " ms, " + (renderPercent) + "%"); + System.out.println("Post: " + FusionAuthOAuth2AuthorizeWorker.timing.post + " ms, Average: " + FusionAuthOAuth2AuthorizeWorker.timing.post / (iterationCount) + " ms, " + (postPercent) + "%"); + System.out.println("Token: " + FusionAuthOAuth2AuthorizeWorker.timing.token + " ms, Average: " + FusionAuthOAuth2AuthorizeWorker.timing.token / (iterationCount) + " ms, " + (tokenPercent) + "%"); + System.out.println("\n\n"); + } - System.out.println("Render: " + FusionAuthOAuth2AuthorizeWorker.timing.render + " ms, Average: " + FusionAuthOAuth2AuthorizeWorker.timing.render / (iterationCount) + " ms, " + (renderPercent) + "%"); - System.out.println("Post: " + FusionAuthOAuth2AuthorizeWorker.timing.post + " ms, Average: " + FusionAuthOAuth2AuthorizeWorker.timing.post / (iterationCount) + " ms, " + (postPercent) + "%"); - System.out.println("Token: " + FusionAuthOAuth2AuthorizeWorker.timing.token + " ms, Average: " + FusionAuthOAuth2AuthorizeWorker.timing.token / (iterationCount) + " ms, " + (tokenPercent) + "%"); - System.out.println("\n\n"); + done = true; + initialized = true; + return this; } - - done = true; - initialized = true; - return this; } public void initialize() { diff --git a/src/main/resources/Create-Applications.json b/src/main/resources/Create-Applications.json index 051140e..0d751cc 100644 --- a/src/main/resources/Create-Applications.json +++ b/src/main/resources/Create-Applications.json @@ -1,6 +1,6 @@ { "loopCount": 100, - "workerCount": 20, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/resources/Create-Tenants.json b/src/main/resources/Create-Tenants.json index b4cf59c..433475a 100644 --- a/src/main/resources/Create-Tenants.json +++ b/src/main/resources/Create-Tenants.json @@ -1,6 +1,6 @@ { "loopCount": 100, - "workerCount": 20, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/resources/HTTP.json b/src/main/resources/HTTP.json index 4ca8b5b..bebf747 100644 --- a/src/main/resources/HTTP.json +++ b/src/main/resources/HTTP.json @@ -1,6 +1,6 @@ { "loopCount": 500000, - "workerCount": 20, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.HTTPWorkerFactory", "attributes": { diff --git a/src/main/resources/OAuth2-AuthorizationCodeGrant.json b/src/main/resources/OAuth2-AuthorizationCodeGrant.json index 97f9913..3dff2f2 100644 --- a/src/main/resources/OAuth2-AuthorizationCodeGrant.json +++ b/src/main/resources/OAuth2-AuthorizationCodeGrant.json @@ -1,6 +1,6 @@ { "loopCount": 100, - "workerCount": 20, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/resources/User-Logins.json b/src/main/resources/User-Logins.json index 895b7c7..2a7d00a 100644 --- a/src/main/resources/User-Logins.json +++ b/src/main/resources/User-Logins.json @@ -1,6 +1,6 @@ { "loopCount": 1000, - "workerCount": 50, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/resources/User-Registrations.json b/src/main/resources/User-Registrations.json index d6ac77d..7eea697 100644 --- a/src/main/resources/User-Registrations.json +++ b/src/main/resources/User-Registrations.json @@ -1,6 +1,6 @@ { "loopCount": 1000, - "workerCount": 10, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/resources/User-RetrieveEmail.json b/src/main/resources/User-RetrieveEmail.json index 6b152e3..58e0836 100644 --- a/src/main/resources/User-RetrieveEmail.json +++ b/src/main/resources/User-RetrieveEmail.json @@ -1,6 +1,6 @@ { "loopCount": 2000, - "workerCount": 25, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/resources/User-Search.json b/src/main/resources/User-Search.json index cbf618d..e18e635 100644 --- a/src/main/resources/User-Search.json +++ b/src/main/resources/User-Search.json @@ -1,6 +1,6 @@ { "loopCount": 2000, - "workerCount": 25, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/resources/User-SearchData.json b/src/main/resources/User-SearchData.json index 46621aa..d0e6a18 100644 --- a/src/main/resources/User-SearchData.json +++ b/src/main/resources/User-SearchData.json @@ -1,6 +1,6 @@ { "loopCount": 2000, - "workerCount": 25, + "workerCount": 100, "workerFactory": { "className": "io.fusionauth.load.FusionAuthWorkerFactory", "attributes": { diff --git a/src/main/script/load-test.sh b/src/main/script/load-test.sh index b835a0a..392741a 100755 --- a/src/main/script/load-test.sh +++ b/src/main/script/load-test.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # -# Copyright (c) 2022, FusionAuth, All Rights Reserved +# Copyright (c) 2022-2025, FusionAuth, All Rights Reserved # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -33,4 +33,4 @@ if [[ $# > 1 && $1 == "--suspend" ]]; then shift fi -~/dev/java/current17/bin/java ${suspend} -cp "${CLASSPATH}" io.fusionauth.load.LoadRunner $@ +~/dev/java/current21/bin/java ${suspend} -cp "${CLASSPATH}" io.fusionauth.load.LoadRunner $@