Skip to content

Commit

Permalink
Add new framework 'today' (TechEmpower#8815)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
TAKETODAY authored Apr 12, 2024
1 parent d49e17b commit 89d83c0
Show file tree
Hide file tree
Showing 17 changed files with 578 additions and 0 deletions.
9 changes: 9 additions & 0 deletions frameworks/Java/today/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build

.idea
today.properties
gradle
26 changes: 26 additions & 0 deletions frameworks/Java/today/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# [TODAY Infrastructure](https://github.com/TAKETODAY/today-infrastructure) Benchmarking Test

## Test URLs
### JSON

http://localhost:8080/json

### PLAINTEXT

http://localhost:8080/plaintext

### DB

http://localhost:8080/db

### QUERY

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

### UPDATE

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

### FORTUNES

http://localhost:8080/fortunes
30 changes: 30 additions & 0 deletions frameworks/Java/today/benchmark_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"framework": "today",
"tests": [
{
"default": {
"json_url": "/json",
"plaintext_url": "/plaintext",
"db_url": "/db",
"query_url": "/queries?queries=",
"fortune_url": "/fortunes",
"update_url": "/updates?queries=",
"port": 8080,
"approach": "Realistic",
"classification": "Fullstack",
"database": "mysql",
"framework": "Today",
"language": "Java",
"flavor": "None",
"orm": "micro",
"platform": "Netty",
"webserver": "None",
"os": "Linux",
"database_os": "Linux",
"display_name": "Today",
"notes": "",
"versus": "None"
}
}
]
}
63 changes: 63 additions & 0 deletions frameworks/Java/today/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
description = "benchmark"

apply plugin: "java"
apply plugin: "application"
apply plugin: 'cn.taketoday.application'
apply plugin: 'io.spring.dependency-management'

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

repositories {
mavenCentral()
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
}

dependencies {
implementation 'cn.taketoday:today-starter-netty'
implementation 'cn.taketoday:today-starter-json'
implementation 'cn.taketoday:today-starter-jdbc'
implementation 'cn.taketoday:today-starter-web'
implementation 'cn.taketoday:today-starter-freemarker'

implementation 'mysql:mysql-connector-java'

implementation 'ch.qos.logback:logback-classic'

implementation('io.netty:netty-transport-native-epoll') {
artifact {
classifier = 'linux-x86_64'
}
}

// implementation('io.netty:netty-transport-native-kqueue') {
// artifact {
// classifier = 'osx-aarch_64'
// }
// }

}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

application {
mainClass = 'cn.taketoday.benchmark.BenchmarkApplication'
applicationDefaultJvmArgs = [
"-server",
"-XX:+UseNUMA",
"-XX:+UseG1GC",
"-XX:+DisableExplicitGC",
"-XX:-StackTraceInThrowable",
"-XX:+UseStringDeduplication",
"-Dinfra.profiles.active=test",
"-Dio.netty.buffer.checkBounds=false",
"-Dio.netty.buffer.checkAccessible=false",
"-Dio.netty.leakDetection.level=disabled",
"--add-opens=java.base/java.nio=ALL-UNNAMED",
"--add-opens=java.base/sun.nio.ch=ALL-UNNAMED"
]
}
20 changes: 20 additions & 0 deletions frameworks/Java/today/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[framework]
name = "today"

[main]
urls.plaintext = "/plaintext"
urls.json = "/json"
urls.db = "/db"
urls.query = "/queries?queries="
urls.update = "/updates?queries="
urls.fortune = "/fortunes"
approach = "Realistic"
classification = "Fullstack"
database = "mysql"
database_os = "Linux"
display_name = "today"
os = "Linux"
orm = "raw"
platform = "Netty"
webserver = "None"
versus = "None"
7 changes: 7 additions & 0 deletions frameworks/Java/today/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version=1.0.0
#infraVersion=4.0.0-Draft.6-SNAPSHOT
infraVersion=4.0.0-Draft.6

org.gradle.caching=true
org.gradle.jvmargs=-Xmx2048m
org.gradle.parallel=true
15 changes: 15 additions & 0 deletions frameworks/Java/today/settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
buildscript {
repositories {
mavenLocal()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots/"
}
mavenCentral()
}

dependencies {
classpath "cn.taketoday:infra-gradle-plugin:$infraVersion"
}
}

rootProject.name = 'today'
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package cn.taketoday.benchmark;

import java.time.ZonedDateTime;

import javax.sql.DataSource;

import cn.taketoday.beans.factory.annotation.DisableAllDependencyInjection;
import cn.taketoday.beans.factory.config.BeanDefinition;
import cn.taketoday.context.annotation.Configuration;
import cn.taketoday.context.annotation.Role;
import cn.taketoday.framework.web.netty.NettyRequestConfig;
import cn.taketoday.framework.web.netty.SendErrorHandler;
import cn.taketoday.jdbc.RepositoryManager;
import cn.taketoday.jdbc.persistence.EntityManager;
import cn.taketoday.stereotype.Component;
import io.netty.handler.codec.http.DefaultHttpHeadersFactory;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpHeadersFactory;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;

import static cn.taketoday.http.HttpHeaders.DATE_FORMATTER;

/**
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
* @since 1.0 2024/3/19 12:59
*/
@DisableAllDependencyInjection
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
@Configuration(proxyBeanMethods = false)
class AppConfig {

private static final DefaultHttpHeadersFactory headersFactory = DefaultHttpHeadersFactory.headersFactory();

@Component
static RepositoryManager repositoryManager(DataSource dataSource) {
return new RepositoryManager(dataSource);
}

@Component
static EntityManager entityManager(RepositoryManager repositoryManager) {
return repositoryManager.getEntityManager();
}

@Component
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
static NettyRequestConfig nettyRequestConfig(SendErrorHandler sendErrorHandler) {
var factory = new DefaultHttpDataFactory(false);
return NettyRequestConfig.forBuilder()
.httpDataFactory(factory)
.sendErrorHandler(sendErrorHandler)
.headersFactory(new HttpHeadersFactory() {

@Override
public HttpHeaders newHeaders() {
HttpHeaders headers = headersFactory.newHeaders();
headers.set("Server", "TODAY");
headers.set("Date", DATE_FORMATTER.format(ZonedDateTime.now()));
return headers;
}

@Override
public HttpHeaders newEmptyHeaders() {
return headersFactory.newEmptyHeaders();
}
})
.secure(false)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package cn.taketoday.benchmark;

import cn.taketoday.framework.Application;
import cn.taketoday.framework.InfraApplication;

@InfraApplication
public class BenchmarkApplication {

public static void main(String[] args) {
Application.run(BenchmarkApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package cn.taketoday.benchmark.http;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.IntStream;

import cn.taketoday.benchmark.model.Fortune;
import cn.taketoday.benchmark.model.World;
import cn.taketoday.http.MediaType;
import cn.taketoday.http.ResponseEntity;
import cn.taketoday.jdbc.persistence.EntityManager;
import cn.taketoday.lang.Nullable;
import cn.taketoday.ui.Model;
import cn.taketoday.web.annotation.GET;
import cn.taketoday.web.annotation.RestController;
import cn.taketoday.web.view.ViewRef;

/**
* @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
* @since 1.0 2024/3/19 12:56
*/
@RestController
final class BenchmarkHttpHandler {

private static final int MIN_WORLD_NUMBER = 1;
private static final int MAX_WORLD_NUMBER = 10_000;

private final EntityManager entityManager;

BenchmarkHttpHandler(EntityManager entityManager) {
this.entityManager = entityManager;
}

@GET("/json")
public ResponseEntity<Map<String, String>> json() {
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(Map.of("message", "Hello, World!"));
}

@GET("/plaintext")
public String plaintext() {
return "Hello, World!";
}

@GET("/db")
public World db() {
return entityManager.findById(World.class, nextInt());
}

@GET("/queries")
public List<World> queries(@Nullable String queries) {
return randomNumbers()
.mapToObj(this::findWorldById)
.limit(parseQueryCount(queries))
.toList();
}

@GET("/updates")
public List<World> updates(@Nullable String queries) {
return randomNumbers()
.mapToObj(this::findWorldById)
.filter(Objects::nonNull)
.peek(world -> {
world.setRandomNumber(nextInt());
entityManager.updateById(world);
})
.limit(parseQueryCount(queries))
.toList();
}

@GET("/fortunes")
public ViewRef fortunes(Model model) {
List<Fortune> fortunes = entityManager.find(Fortune.class);
fortunes.add(new Fortune(0, "Additional fortune added at request time."));
fortunes.sort(Comparator.comparing(Fortune::getMessage));

model.addAttribute("fortunes", fortunes);
return ViewRef.forViewName("fortunes");
}

@Nullable
private World findWorldById(int id) {
return entityManager.findById(World.class, boxed[id]);
}

//

private static IntStream randomNumbers() {
return ThreadLocalRandom.current()
.ints(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER)
.distinct();
}

private static final Integer[] boxed = IntStream.range(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER + 1)
.boxed()
.toArray(Integer[]::new);

private static Integer nextInt() {
return boxed[ThreadLocalRandom.current().nextInt(MIN_WORLD_NUMBER, MAX_WORLD_NUMBER)];
}

private static int parseQueryCount(@Nullable String textValue) {
if (textValue == null) {
return 1;
}
int parsedValue;
try {
parsedValue = Integer.parseInt(textValue);
}
catch (NumberFormatException e) {
return 1;
}
return Math.min(500, Math.max(1, parsedValue));
}

}
Loading

0 comments on commit 89d83c0

Please sign in to comment.