Skip to content

Commit b73a8a2

Browse files
authored
Add cached query tests (#9680)
* Add new framework Java/today * change build config * ⬆️ 升级版本 4.0.0-Draft.6 * 更新 /updates API * 打开日志 * 🔥 删除 /updates API 偶尔会出错,目前尚未找到原因 * 🎨 更新 /updates API * 🎨 添加 epoll 支持 * 🔥 remove all of the files that aren't necessary for the tests * 🎨 .gitignore * 🎨 优化构建 * ✨ 更新框架,新增 cached_query_url * 🎨 优化使用方式 * 🎨 优化使用方式 * 🎨 * 🎨 * 🎨 修改 cached queries 地址
1 parent 83ee3c9 commit b73a8a2

19 files changed

+205
-92
lines changed

frameworks/Java/today/.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ build
66

77
.idea
88
today.properties
9-
gradle
9+
gradle
10+
gradlew

frameworks/Java/today/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ http://localhost:8080/db
1717

1818
http://localhost:8080/queries?queries=
1919

20+
### Caching QUERY
21+
22+
http://localhost:8080/cached-queries?count=10
23+
2024
### UPDATE
2125

2226
http://localhost:8080/update?queries=

frameworks/Java/today/benchmark_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"query_url": "/queries?queries=",
1010
"fortune_url": "/fortunes",
1111
"update_url": "/updates?queries=",
12+
"cached_query_url": "/cached-queries?count=",
1213
"port": 8080,
1314
"approach": "Realistic",
1415
"classification": "Fullstack",
@@ -21,7 +22,7 @@
2122
"webserver": "None",
2223
"os": "Linux",
2324
"database_os": "Linux",
24-
"display_name": "Today",
25+
"display_name": "TODAY",
2526
"notes": "",
2627
"versus": "None"
2728
}

frameworks/Java/today/build.gradle

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
description = "benchmark"
22

3-
apply plugin: "java"
4-
apply plugin: "application"
5-
apply plugin: 'cn.taketoday.application'
6-
apply plugin: 'io.spring.dependency-management'
3+
apply plugin: 'java'
4+
apply plugin: 'application'
5+
apply plugin: 'infra.application'
76

87
configure(allprojects) {
98
group = "cn.taketoday.benchmark"
109

1110
repositories {
11+
mavenLocal()
1212
mavenCentral()
13-
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
13+
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
1414
}
1515
}
1616

@@ -24,13 +24,20 @@ dependencies {
2424
implementation 'mysql:mysql-connector-java'
2525

2626
implementation 'ch.qos.logback:logback-classic'
27+
implementation 'com.github.ben-manes.caffeine:caffeine'
2728

2829
implementation('io.netty:netty-transport-native-epoll') {
2930
artifact {
3031
classifier = 'linux-x86_64'
3132
}
3233
}
3334

35+
implementation('io.netty.incubator:netty-incubator-transport-native-io_uring:0.0.21.Final') {
36+
artifact {
37+
classifier = 'linux-x86_64'
38+
}
39+
}
40+
3441
// implementation('io.netty:netty-transport-native-kqueue') {
3542
// artifact {
3643
// classifier = 'osx-aarch_64'
@@ -40,23 +47,24 @@ dependencies {
4047
}
4148

4249
java {
43-
sourceCompatibility = JavaVersion.VERSION_17
44-
targetCompatibility = JavaVersion.VERSION_17
50+
sourceCompatibility = JavaVersion.VERSION_21
51+
targetCompatibility = JavaVersion.VERSION_21
4552
}
4653

4754
application {
4855
mainClass = 'cn.taketoday.benchmark.BenchmarkApplication'
4956
applicationDefaultJvmArgs = [
5057
"-server",
58+
"-Xms2G",
59+
"-Xmx2G",
5160
"-XX:+UseNUMA",
52-
"-XX:+UseG1GC",
53-
"-XX:+DisableExplicitGC",
54-
"-XX:-StackTraceInThrowable",
5561
"-XX:+UseStringDeduplication",
5662
"-Dinfra.profiles.active=test",
5763
"-Dio.netty.buffer.checkBounds=false",
5864
"-Dio.netty.buffer.checkAccessible=false",
5965
"-Dio.netty.leakDetection.level=disabled",
66+
"-Dio.netty.iouring.iosqeAsyncThreshold=32000",
67+
"-Djava.lang.Integer.IntegerCache.high=10000",
6068
"--add-opens=java.base/java.nio=ALL-UNNAMED",
6169
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
6270
]

frameworks/Java/today/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ urls.db = "/db"
88
urls.query = "/queries?queries="
99
urls.update = "/updates?queries="
1010
urls.fortune = "/fortunes"
11+
urls.cached_query = "/cached-queries?count="
1112
approach = "Realistic"
1213
classification = "Fullstack"
1314
database = "mysql"

frameworks/Java/today/gradle.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
version=1.0.0
2-
#infraVersion=4.0.0-Draft.6-SNAPSHOT
3-
infraVersion=4.0.0-Draft.6
1+
version=1.1.0
2+
#infraVersion=5.0-Draft.2
3+
infraVersion=5.0-Draft.2-SNAPSHOT
44

55
org.gradle.caching=true
66
org.gradle.jvmargs=-Xmx2048m

frameworks/Java/today/src/main/java/cn/taketoday/benchmark/AppConfig.java

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,26 @@
44

55
import javax.sql.DataSource;
66

7-
import cn.taketoday.beans.factory.annotation.DisableAllDependencyInjection;
8-
import cn.taketoday.beans.factory.config.BeanDefinition;
9-
import cn.taketoday.context.annotation.Configuration;
10-
import cn.taketoday.context.annotation.Role;
11-
import cn.taketoday.framework.web.netty.NettyRequestConfig;
12-
import cn.taketoday.framework.web.netty.SendErrorHandler;
13-
import cn.taketoday.jdbc.RepositoryManager;
14-
import cn.taketoday.jdbc.persistence.EntityManager;
15-
import cn.taketoday.stereotype.Component;
16-
import io.netty.handler.codec.http.DefaultHttpHeadersFactory;
7+
import infra.beans.factory.annotation.DisableAllDependencyInjection;
8+
import infra.beans.factory.config.BeanDefinition;
9+
import infra.context.annotation.Configuration;
10+
import infra.context.annotation.Role;
11+
import infra.jdbc.RepositoryManager;
12+
import infra.persistence.EntityManager;
13+
import infra.stereotype.Component;
14+
import infra.web.server.WebServerFactoryCustomizer;
15+
import infra.web.server.error.SendErrorHandler;
16+
import infra.web.server.support.NettyRequestConfig;
17+
import infra.web.server.support.NettyWebServerFactory;
18+
import io.netty.handler.codec.http.DefaultHttpHeaders;
1719
import io.netty.handler.codec.http.HttpHeaders;
1820
import io.netty.handler.codec.http.HttpHeadersFactory;
1921
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
22+
import io.netty.incubator.channel.uring.IOUring;
23+
import io.netty.incubator.channel.uring.IOUringEventLoopGroup;
24+
import io.netty.incubator.channel.uring.IOUringServerSocketChannel;
2025

21-
import static cn.taketoday.http.HttpHeaders.DATE_FORMATTER;
26+
import static infra.http.HttpHeaders.DATE_FORMATTER;
2227

2328
/**
2429
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
@@ -29,42 +34,60 @@
2934
@Configuration(proxyBeanMethods = false)
3035
class AppConfig {
3136

32-
private static final DefaultHttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory();
33-
3437
@Component
35-
static RepositoryManager repositoryManager(DataSource dataSource) {
38+
public static RepositoryManager repositoryManager(DataSource dataSource) {
3639
return new RepositoryManager(dataSource);
3740
}
3841

3942
@Component
40-
static EntityManager entityManager(RepositoryManager repositoryManager) {
43+
public static EntityManager entityManager(RepositoryManager repositoryManager) {
4144
return repositoryManager.getEntityManager();
4245
}
4346

47+
@Component
48+
public static WebServerFactoryCustomizer<NettyWebServerFactory> factoryWebServerFactoryCustomizer() {
49+
return factory -> {
50+
if (IOUring.isAvailable()) {
51+
IOUringEventLoopGroup loopGroup = new IOUringEventLoopGroup();
52+
factory.setAcceptorGroup(loopGroup);
53+
factory.setWorkerGroup(loopGroup);
54+
factory.setSocketChannel(IOUringServerSocketChannel.class);
55+
}
56+
};
57+
}
58+
4459
@Component
4560
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
46-
static NettyRequestConfig nettyRequestConfig(SendErrorHandler sendErrorHandler) {
61+
public static NettyRequestConfig nettyRequestConfig(SendErrorHandler sendErrorHandler) {
4762
var factory = new DefaultHttpDataFactory(false);
48-
return NettyRequestConfig.forBuilder()
63+
64+
return NettyRequestConfig.forBuilder(false)
4965
.httpDataFactory(factory)
5066
.sendErrorHandler(sendErrorHandler)
5167
.headersFactory(new HttpHeadersFactory() {
5268

5369
@Override
5470
public HttpHeaders newHeaders() {
55-
HttpHeaders headers = headersFactory.newHeaders();
71+
HttpHeaders headers = new ResponseHeaders();
5672
headers.set("Server", "TODAY");
5773
headers.set("Date", DATE_FORMATTER.format(ZonedDateTime.now()));
5874
return headers;
5975
}
6076

6177
@Override
6278
public HttpHeaders newEmptyHeaders() {
63-
return headersFactory.newEmptyHeaders();
79+
return new ResponseHeaders();
6480
}
6581
})
66-
.secure(false)
6782
.build();
6883
}
6984

85+
static class ResponseHeaders extends DefaultHttpHeaders {
86+
87+
public ResponseHeaders() {
88+
super(name -> { }, v -> { });
89+
}
90+
91+
}
92+
7093
}

frameworks/Java/today/src/main/java/cn/taketoday/benchmark/BenchmarkApplication.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package cn.taketoday.benchmark;
22

3-
import cn.taketoday.framework.Application;
4-
import cn.taketoday.framework.InfraApplication;
3+
import infra.app.Application;
4+
import infra.app.InfraApplication;
55

66
@InfraApplication
77
public class BenchmarkApplication {

frameworks/Java/today/src/main/java/cn/taketoday/benchmark/http/BenchmarkHttpHandler.java

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22

33
import java.util.Comparator;
44
import java.util.List;
5-
import java.util.Map;
6-
import java.util.Objects;
75
import java.util.concurrent.ThreadLocalRandom;
86
import java.util.stream.IntStream;
97

108
import cn.taketoday.benchmark.model.Fortune;
9+
import cn.taketoday.benchmark.model.Message;
1110
import cn.taketoday.benchmark.model.World;
12-
import cn.taketoday.http.MediaType;
13-
import cn.taketoday.http.ResponseEntity;
14-
import cn.taketoday.jdbc.persistence.EntityManager;
15-
import cn.taketoday.lang.Nullable;
16-
import cn.taketoday.ui.Model;
17-
import cn.taketoday.web.annotation.GET;
18-
import cn.taketoday.web.annotation.RestController;
19-
import cn.taketoday.web.view.ViewRef;
11+
import infra.http.MediaType;
12+
import infra.http.ResponseEntity;
13+
import infra.lang.Nullable;
14+
import infra.persistence.EntityManager;
15+
import infra.ui.Model;
16+
import infra.util.concurrent.Future;
17+
import infra.web.annotation.GET;
18+
import infra.web.annotation.RestController;
19+
import infra.web.view.ViewRef;
2020

2121
/**
2222
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
@@ -26,50 +26,57 @@
2626
final class BenchmarkHttpHandler {
2727

2828
private static final int MIN_WORLD_NUMBER = 1;
29+
2930
private static final int MAX_WORLD_NUMBER = 10_000;
3031

3132
private final EntityManager entityManager;
3233

34+
private final WorldCache worldCache;
35+
3336
BenchmarkHttpHandler(EntityManager entityManager) {
3437
this.entityManager = entityManager;
38+
this.worldCache = new WorldCache(entityManager.find(World.class));
3539
}
3640

3741
@GET("/json")
38-
public ResponseEntity<Map<String, String>> json() {
42+
public ResponseEntity<Message> json() {
3943
return ResponseEntity.ok()
4044
.contentType(MediaType.APPLICATION_JSON)
41-
.body(Map.of("message", "Hello, World!"));
45+
.body(new Message("Hello, World!"));
4246
}
4347

4448
@GET("/plaintext")
4549
public String plaintext() {
4650
return "Hello, World!";
4751
}
4852

53+
@Nullable
4954
@GET("/db")
5055
public World db() {
5156
return entityManager.findById(World.class, nextInt());
5257
}
5358

5459
@GET("/queries")
55-
public List<World> queries(@Nullable String queries) {
56-
return randomNumbers()
57-
.mapToObj(this::findWorldById)
58-
.limit(parseQueryCount(queries))
59-
.toList();
60+
public Future<List<World>> queries(@Nullable String queries) {
61+
return Future.combine(randomNumbers().limit(parseQueryCount(queries)).mapToObj(this::findWorldByIdFuture))
62+
.asList();
63+
}
64+
65+
@GET("/cached-queries")
66+
public List<World> cachedQueries(@Nullable String count) {
67+
return worldCache.getCachedWorld(parseQueryCount(count));
6068
}
6169

6270
@GET("/updates")
63-
public List<World> updates(@Nullable String queries) {
64-
return randomNumbers()
65-
.mapToObj(this::findWorldById)
66-
.filter(Objects::nonNull)
67-
.peek(world -> {
71+
public Future<List<World>> updates(@Nullable String queries) {
72+
return Future.combine(randomNumbers()
73+
.limit(parseQueryCount(queries))
74+
.mapToObj(this::findWorldByIdFuture)
75+
.map(worldFuture -> worldFuture.map(world -> {
6876
world.setRandomNumber(nextInt());
6977
entityManager.updateById(world);
70-
})
71-
.limit(parseQueryCount(queries))
72-
.toList();
78+
return world;
79+
}))).asList();
7380
}
7481

7582
@GET("/fortunes")
@@ -82,9 +89,13 @@ public ViewRef fortunes(Model model) {
8289
return ViewRef.forViewName("fortunes");
8390
}
8491

92+
private Future<World> findWorldByIdFuture(int id) {
93+
return Future.run(() -> findWorldById(id));
94+
}
95+
8596
@Nullable
8697
private World findWorldById(int id) {
87-
return entityManager.findById(World.class, boxed[id]);
98+
return entityManager.findById(World.class, id);
8899
}
89100

90101
//
@@ -95,12 +106,8 @@ private static IntStream randomNumbers() {
95106
.distinct();
96107
}
97108

98-
private static final Integer[] boxed = IntStream.range(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER + 1)
99-
.boxed()
100-
.toArray(Integer[]::new);
101-
102-
private static Integer nextInt() {
103-
return boxed[ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER)];
109+
private static int nextInt() {
110+
return ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER);
104111
}
105112

106113
private static int parseQueryCount(@Nullable String textValue) {

0 commit comments

Comments
 (0)