diff --git a/frameworks/Java/spring-webflux/src/main/java/benchmark/Utils.java b/frameworks/Java/spring-webflux/src/main/java/benchmark/Utils.java new file mode 100644 index 00000000000..4631be27f11 --- /dev/null +++ b/frameworks/Java/spring-webflux/src/main/java/benchmark/Utils.java @@ -0,0 +1,19 @@ +package benchmark; + +import java.util.concurrent.ThreadLocalRandom; +import java.util.stream.IntStream; + +abstract public class Utils { + + private static final int MIN_WORLD_NUMBER = 1; + private static final int MAX_WORLD_NUMBER_PLUS_ONE = 10_001; + + public static int randomWorldNumber() { + return ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE); + } + + public static IntStream randomWorldNumbers() { + return ThreadLocalRandom.current().ints(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE).distinct(); + } + +} diff --git a/frameworks/Java/spring-webflux/src/main/java/benchmark/repository/R2dbcDbRepository.java b/frameworks/Java/spring-webflux/src/main/java/benchmark/repository/R2dbcDbRepository.java index c7cfb89dea4..3cbf5f66d4a 100644 --- a/frameworks/Java/spring-webflux/src/main/java/benchmark/repository/R2dbcDbRepository.java +++ b/frameworks/Java/spring-webflux/src/main/java/benchmark/repository/R2dbcDbRepository.java @@ -1,20 +1,27 @@ package benchmark.repository; -import benchmark.model.Fortune; -import benchmark.model.World; import org.springframework.context.annotation.Profile; import org.springframework.r2dbc.core.DatabaseClient; import org.springframework.stereotype.Component; + +import benchmark.model.Fortune; +import benchmark.model.World; +import io.r2dbc.spi.Connection; +import io.r2dbc.spi.ConnectionFactory; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component @Profile("r2dbc") public class R2dbcDbRepository implements DbRepository { + private final DatabaseClient databaseClient; + private final ConnectionFactory connectionFactory; + private final ThreadLocal> conn = new ThreadLocal<>(); public R2dbcDbRepository(DatabaseClient databaseClient) { this.databaseClient = databaseClient; + this.connectionFactory = databaseClient.getConnectionFactory(); } @Override @@ -24,10 +31,9 @@ public Mono getWorld(int id) { .bind("$1", id) .mapProperties(World.class) .first(); - } - public Mono updateWorld(World world) { + private Mono updateWorld(World world) { return databaseClient .sql("UPDATE world SET randomnumber=$2 WHERE id = $1") .bind("$1", world.id) @@ -37,6 +43,8 @@ public Mono updateWorld(World world) { .map(count -> world); } + + @Override public Mono findAndUpdateWorld(int id, int randomNumber) { return getWorld(id).flatMap(world -> { world.randomnumber = randomNumber; @@ -46,9 +54,16 @@ public Mono findAndUpdateWorld(int id, int randomNumber) { @Override public Flux fortunes() { - return databaseClient - .sql("SELECT id, message FROM fortune") - .mapProperties(Fortune.class) - .all(); + return getConnection() + .flatMapMany(conn -> conn.createStatement("SELECT id, message FROM " + "fortune").execute()) + .flatMap(result -> result.map(r -> new Fortune(r.get(0, Integer.class), r.get(1, String.class)))); } + + private Mono getConnection() { + if (this.conn.get() == null) { + this.conn.set(Mono.from(connectionFactory.create()).cache()); + } + return this.conn.get(); + } + } \ No newline at end of file diff --git a/frameworks/Java/spring-webflux/src/main/java/benchmark/web/DbHandler.java b/frameworks/Java/spring-webflux/src/main/java/benchmark/web/DbHandler.java index 970ace1d46d..e85d9c5be15 100644 --- a/frameworks/Java/spring-webflux/src/main/java/benchmark/web/DbHandler.java +++ b/frameworks/Java/spring-webflux/src/main/java/benchmark/web/DbHandler.java @@ -1,8 +1,8 @@ package benchmark.web; import java.util.List; -import java.util.concurrent.ThreadLocalRandom; +import benchmark.Utils; import benchmark.model.Fortune; import benchmark.model.World; import benchmark.repository.DbRepository; @@ -29,7 +29,7 @@ public DbHandler(DbRepository dbRepository) { } public Mono db(ServerRequest request) { - int id = randomWorldNumber(); + int id = Utils.randomWorldNumber(); Mono world = dbRepository.getWorld(id) .switchIfEmpty(Mono.error(new Exception("No World found with Id: " + id))); @@ -41,8 +41,8 @@ public Mono db(ServerRequest request) { public Mono queries(ServerRequest request) { int queries = parseQueryCount(request.queryParams().getFirst("queries")); - Mono> worlds = Flux.range(0, queries) - .flatMap(i -> dbRepository.getWorld(randomWorldNumber())) + Mono> worlds = Flux.fromStream(Utils.randomWorldNumbers().limit(queries).boxed()) + .flatMap(dbRepository::getWorld) .collectList(); return ServerResponse.ok() @@ -67,8 +67,8 @@ private static int parseQueryCount(String maybeTextValue) { public Mono updates(ServerRequest request) { int queries = parseQueryCount(request.queryParams().getFirst("queries")); - Mono> worlds = Flux.range(0, queries) - .flatMap(i -> dbRepository.findAndUpdateWorld(randomWorldNumber(), randomWorldNumber())) + Mono> worlds = Flux.fromStream(Utils.randomWorldNumbers().limit(queries).boxed()) + .flatMap(i -> dbRepository.findAndUpdateWorld(i, Utils.randomWorldNumber())) .collectList(); return ServerResponse.ok() @@ -87,7 +87,4 @@ public Mono fortunes(ServerRequest request) { .bodyValue(JStachio.render(new Fortunes(fortunes)))); } - private static int randomWorldNumber() { - return 1 + ThreadLocalRandom.current().nextInt(10000); - } } \ No newline at end of file diff --git a/frameworks/Java/spring/src/main/java/hello/web/DbHandler.java b/frameworks/Java/spring/src/main/java/hello/web/DbHandler.java index affb752268f..983eb79f6b9 100644 --- a/frameworks/Java/spring/src/main/java/hello/web/DbHandler.java +++ b/frameworks/Java/spring/src/main/java/hello/web/DbHandler.java @@ -1,6 +1,7 @@ package hello.web; import java.util.Collections; +import java.util.Comparator; import java.util.List; import hello.Utils; @@ -52,6 +53,7 @@ ServerResponse updates(ServerRequest request) { world.randomNumber = randomNumber; return world; }).limit(queries) + .sorted(Comparator.comparingInt(w -> w.id)) .toList(); dbRepository.updateWorlds(worlds); return ServerResponse.ok()