Skip to content

Commit 4d021bf

Browse files
committed
[spring-webflux] Improve database tests
- Improve the test reliability with a better random number generation mechanism - Improve the scalability of fortune test
1 parent 643bbbd commit 4d021bf

File tree

3 files changed

+48
-17
lines changed

3 files changed

+48
-17
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package benchmark;
2+
3+
import java.util.concurrent.ThreadLocalRandom;
4+
import java.util.stream.IntStream;
5+
6+
abstract public class Utils {
7+
8+
private static final int MIN_WORLD_NUMBER = 1;
9+
private static final int MAX_WORLD_NUMBER_PLUS_ONE = 10_001;
10+
11+
public static int randomWorldNumber() {
12+
return ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE);
13+
}
14+
15+
public static IntStream randomWorldNumbers() {
16+
return ThreadLocalRandom.current().ints(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER_PLUS_ONE).distinct();
17+
}
18+
19+
}
Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,27 @@
11
package benchmark.repository;
22

3-
import benchmark.model.Fortune;
4-
import benchmark.model.World;
53
import org.springframework.context.annotation.Profile;
64
import org.springframework.r2dbc.core.DatabaseClient;
75
import org.springframework.stereotype.Component;
6+
7+
import benchmark.model.Fortune;
8+
import benchmark.model.World;
9+
import io.r2dbc.spi.Connection;
10+
import io.r2dbc.spi.ConnectionFactory;
811
import reactor.core.publisher.Flux;
912
import reactor.core.publisher.Mono;
1013

1114
@Component
1215
@Profile("r2dbc")
1316
public class R2dbcDbRepository implements DbRepository {
17+
1418
private final DatabaseClient databaseClient;
19+
private final ConnectionFactory connectionFactory;
20+
private final ThreadLocal<Mono<? extends Connection>> conn = new ThreadLocal<>();
1521

1622
public R2dbcDbRepository(DatabaseClient databaseClient) {
1723
this.databaseClient = databaseClient;
24+
this.connectionFactory = databaseClient.getConnectionFactory();
1825
}
1926

2027
@Override
@@ -24,10 +31,9 @@ public Mono<World> getWorld(int id) {
2431
.bind("$1", id)
2532
.mapProperties(World.class)
2633
.first();
27-
2834
}
2935

30-
public Mono<World> updateWorld(World world) {
36+
private Mono<World> updateWorld(World world) {
3137
return databaseClient
3238
.sql("UPDATE world SET randomnumber=$2 WHERE id = $1")
3339
.bind("$1", world.id)
@@ -37,6 +43,8 @@ public Mono<World> updateWorld(World world) {
3743
.map(count -> world);
3844
}
3945

46+
47+
@Override
4048
public Mono<World> findAndUpdateWorld(int id, int randomNumber) {
4149
return getWorld(id).flatMap(world -> {
4250
world.randomnumber = randomNumber;
@@ -46,9 +54,16 @@ public Mono<World> findAndUpdateWorld(int id, int randomNumber) {
4654

4755
@Override
4856
public Flux<Fortune> fortunes() {
49-
return databaseClient
50-
.sql("SELECT id, message FROM fortune")
51-
.mapProperties(Fortune.class)
52-
.all();
57+
return getConnection()
58+
.flatMapMany(conn -> conn.createStatement("SELECT id, message FROM " + "fortune").execute())
59+
.flatMap(result -> result.map(r -> new Fortune(r.get(0, Integer.class), r.get(1, String.class))));
5360
}
61+
62+
private Mono<? extends Connection> getConnection() {
63+
if (this.conn.get() == null) {
64+
this.conn.set(Mono.from(connectionFactory.create()).cache());
65+
}
66+
return this.conn.get();
67+
}
68+
5469
}

frameworks/Java/spring-webflux/src/main/java/benchmark/web/DbHandler.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package benchmark.web;
22

33
import java.util.List;
4-
import java.util.concurrent.ThreadLocalRandom;
54

5+
import benchmark.Utils;
66
import benchmark.model.Fortune;
77
import benchmark.model.World;
88
import benchmark.repository.DbRepository;
@@ -29,7 +29,7 @@ public DbHandler(DbRepository dbRepository) {
2929
}
3030

3131
public Mono<ServerResponse> db(ServerRequest request) {
32-
int id = randomWorldNumber();
32+
int id = Utils.randomWorldNumber();
3333
Mono<World> world = dbRepository.getWorld(id)
3434
.switchIfEmpty(Mono.error(new Exception("No World found with Id: " + id)));
3535

@@ -41,8 +41,8 @@ public Mono<ServerResponse> db(ServerRequest request) {
4141
public Mono<ServerResponse> queries(ServerRequest request) {
4242
int queries = parseQueryCount(request.queryParams().getFirst("queries"));
4343

44-
Mono<List<World>> worlds = Flux.range(0, queries)
45-
.flatMap(i -> dbRepository.getWorld(randomWorldNumber()))
44+
Mono<List<World>> worlds = Flux.fromStream(Utils.randomWorldNumbers().limit(queries).boxed())
45+
.flatMap(dbRepository::getWorld)
4646
.collectList();
4747

4848
return ServerResponse.ok()
@@ -67,8 +67,8 @@ private static int parseQueryCount(String maybeTextValue) {
6767
public Mono<ServerResponse> updates(ServerRequest request) {
6868
int queries = parseQueryCount(request.queryParams().getFirst("queries"));
6969

70-
Mono<List<World>> worlds = Flux.range(0, queries)
71-
.flatMap(i -> dbRepository.findAndUpdateWorld(randomWorldNumber(), randomWorldNumber()))
70+
Mono<List<World>> worlds = Flux.fromStream(Utils.randomWorldNumbers().limit(queries).boxed())
71+
.flatMap(i -> dbRepository.findAndUpdateWorld(i, Utils.randomWorldNumber()))
7272
.collectList();
7373

7474
return ServerResponse.ok()
@@ -87,7 +87,4 @@ public Mono<ServerResponse> fortunes(ServerRequest request) {
8787
.bodyValue(JStachio.render(new Fortunes(fortunes))));
8888
}
8989

90-
private static int randomWorldNumber() {
91-
return 1 + ThreadLocalRandom.current().nextInt(10000);
92-
}
9390
}

0 commit comments

Comments
 (0)