Skip to content

Commit 1a59f43

Browse files
committed
[spring-webflux] Improve database tests
- Improve the test reliability with a better random number generation mechanism - Improve the scalability of db, query and fortune tests
1 parent 85ff491 commit 1a59f43

File tree

3 files changed

+63
-26
lines changed

3 files changed

+63
-26
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: 38 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,41 @@
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
2128
public Mono<World> getWorld(int id) {
22-
return databaseClient
23-
.sql("SELECT id, randomnumber FROM world WHERE id = $1")
24-
.bind("$1", id)
25-
.mapProperties(World.class)
26-
.first();
27-
29+
return getConnection().flatMap(conn -> Mono
30+
.from(conn.createStatement("SELECT id, randomnumber FROM world WHERE id = $1")
31+
.bind("$1", id)
32+
.execute())
33+
.flatMap(result -> Mono.from(result.map((row, rowMetadata) ->
34+
new World(row.get("id", Integer.class), row.get("randomnumber", Integer.class)))))
35+
.single());
2836
}
2937

30-
public Mono<World> updateWorld(World world) {
38+
private Mono<World> updateWorld(World world) {
3139
return databaseClient
3240
.sql("UPDATE world SET randomnumber=$2 WHERE id = $1")
3341
.bind("$1", world.id)
@@ -37,18 +45,31 @@ public Mono<World> updateWorld(World world) {
3745
.map(count -> world);
3846
}
3947

48+
49+
@Override
4050
public Mono<World> findAndUpdateWorld(int id, int randomNumber) {
41-
return getWorld(id).flatMap(world -> {
42-
world.randomnumber = randomNumber;
43-
return updateWorld(world);
44-
});
51+
return databaseClient.sql("SELECT id, randomnumber FROM world WHERE id = $1")
52+
.bind("$1", id)
53+
.map((row, rowMetadata) -> new World(row.get("id", Integer.class),
54+
row.get("randomnumber", Integer.class)))
55+
.first().flatMap(world -> {
56+
world.randomnumber = randomNumber;
57+
return updateWorld(world);
58+
});
4559
}
4660

4761
@Override
4862
public Flux<Fortune> fortunes() {
49-
return databaseClient
50-
.sql("SELECT id, message FROM fortune")
51-
.mapProperties(Fortune.class)
52-
.all();
63+
return getConnection()
64+
.flatMapMany(conn -> conn.createStatement("SELECT id, message FROM " + "fortune").execute())
65+
.flatMap(result -> result.map(r -> new Fortune(r.get(0, Integer.class), r.get(1, String.class))));
66+
}
67+
68+
private Mono<? extends Connection> getConnection() {
69+
if (this.conn.get() == null) {
70+
this.conn.set(Mono.from(connectionFactory.create()).cache());
71+
}
72+
return this.conn.get();
5373
}
74+
5475
}

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)