Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
696cb74740
|
|||
59f267426c
|
@@ -5,8 +5,6 @@ on:
|
||||
- '*'
|
||||
jobs:
|
||||
build:
|
||||
env:
|
||||
RUNNER_TOOL_CACHE: /toolcache
|
||||
runs-on: hostinger
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
|
26
benchmark/build.gradle
Normal file
26
benchmark/build.gradle
Normal file
@@ -0,0 +1,26 @@
|
||||
plugins {
|
||||
alias catalog.plugins.gradle.jmh
|
||||
alias catalog.plugins.lombok
|
||||
}
|
||||
|
||||
import me.champeau.jmh.JMHTask
|
||||
|
||||
dependencies {
|
||||
implementation rootProject
|
||||
|
||||
implementation catalog.jwo
|
||||
implementation catalog.xz
|
||||
implementation catalog.jackson.databind
|
||||
|
||||
jmhAnnotationProcessor catalog.lombok
|
||||
}
|
||||
|
||||
jmh {
|
||||
threads = 4
|
||||
iterations = 2
|
||||
fork = 1
|
||||
warmupIterations = 1
|
||||
warmupForks = 0
|
||||
resultFormat = 'JSON'
|
||||
}
|
||||
|
170
benchmark/src/jmh/java/net/woggioni/gbcs/benchmark/Main.java
Normal file
170
benchmark/src/jmh/java/net/woggioni/gbcs/benchmark/Main.java
Normal file
@@ -0,0 +1,170 @@
|
||||
package net.woggioni.gbcs.benchmark;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.SneakyThrows;
|
||||
import org.openjdk.jmh.annotations.Benchmark;
|
||||
import org.openjdk.jmh.annotations.BenchmarkMode;
|
||||
import org.openjdk.jmh.annotations.Level;
|
||||
import org.openjdk.jmh.annotations.Mode;
|
||||
import org.openjdk.jmh.annotations.OutputTimeUnit;
|
||||
import org.openjdk.jmh.annotations.Scope;
|
||||
import org.openjdk.jmh.annotations.Setup;
|
||||
import org.openjdk.jmh.annotations.State;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class Main {
|
||||
|
||||
@SneakyThrows
|
||||
private static Properties loadProperties() {
|
||||
Properties properties = new Properties();
|
||||
try (final var is = Main.class.getResourceAsStream("/benchmark.properties")) {
|
||||
properties.load(is);
|
||||
}
|
||||
return properties;
|
||||
}
|
||||
|
||||
private static final Properties properties = loadProperties();
|
||||
|
||||
@State(Scope.Thread)
|
||||
public static class ExecutionPlan {
|
||||
private final Random random = new Random(101325);
|
||||
|
||||
@Getter
|
||||
private final HttpClient client = HttpClient.newHttpClient();
|
||||
|
||||
private final Map<String, byte[]> entries = new HashMap<>();
|
||||
|
||||
public final Map<String, byte[]> getEntries() {
|
||||
return Collections.unmodifiableMap(entries);
|
||||
}
|
||||
|
||||
public Map.Entry<String, byte[]> newEntry() {
|
||||
final var keyBuffer = new byte[0x20];
|
||||
random.nextBytes(keyBuffer);
|
||||
final var key = Base64.getUrlEncoder().encodeToString(keyBuffer);
|
||||
final var value = new byte[0x1000];
|
||||
random.nextBytes(value);
|
||||
return Map.entry(key, value);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public HttpRequest.Builder newRequestBuilder(String key) {
|
||||
final var requestBuilder = HttpRequest.newBuilder()
|
||||
.uri(getServerURI().resolve(key));
|
||||
String user = getUser();
|
||||
if (user != null) {
|
||||
requestBuilder.header("Authorization", buildAuthorizationHeader(user, getPassword()));
|
||||
}
|
||||
return requestBuilder;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public URI getServerURI() {
|
||||
return new URI(properties.getProperty("gbcs.server.url"));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public String getUser() {
|
||||
return Optional.ofNullable(properties.getProperty("gbcs.server.username"))
|
||||
.filter(Predicate.not(String::isEmpty))
|
||||
.orElse(null);
|
||||
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
public String getPassword() {
|
||||
return Optional.ofNullable(properties.getProperty("gbcs.server.password"))
|
||||
.filter(Predicate.not(String::isEmpty))
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
private String buildAuthorizationHeader(String user, String password) {
|
||||
final var b64 = Base64.getEncoder().encode(String.format("%s:%s", user, password).getBytes(StandardCharsets.UTF_8));
|
||||
return "Basic " + new String(b64);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
@Setup(Level.Trial)
|
||||
public void setUp() {
|
||||
try (final var client = HttpClient.newHttpClient()) {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
final var pair = newEntry();
|
||||
final var requestBuilder = newRequestBuilder(pair.getKey())
|
||||
.header("Content-Type", "application/octet-stream")
|
||||
.PUT(HttpRequest.BodyPublishers.ofByteArray(pair.getValue()));
|
||||
final var response = client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofString());
|
||||
if (201 != response.statusCode()) {
|
||||
throw new IllegalStateException(Integer.toString(response.statusCode()));
|
||||
} else {
|
||||
entries.put(pair.getKey(), pair.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Iterator<Map.Entry<String, byte[]>> it = null;
|
||||
|
||||
private Map.Entry<String, byte[]> nextEntry() {
|
||||
if (it == null || !it.hasNext()) {
|
||||
it = getEntries().entrySet().iterator();
|
||||
}
|
||||
return it.next();
|
||||
}
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
public void get(ExecutionPlan plan) {
|
||||
final var client = plan.getClient();
|
||||
final var entry = plan.nextEntry();
|
||||
final var requestBuilder = plan.newRequestBuilder(entry.getKey())
|
||||
.header("Accept", "application/octet-stream")
|
||||
.GET();
|
||||
final var response = client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofByteArray());
|
||||
if (200 != response.statusCode()) {
|
||||
throw new IllegalStateException(Integer.toString(response.statusCode()));
|
||||
} else {
|
||||
if (!Arrays.equals(entry.getValue(), response.body())) {
|
||||
throw new IllegalStateException("Retrieved unexpected value");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
@Benchmark
|
||||
@BenchmarkMode(Mode.Throughput)
|
||||
@OutputTimeUnit(TimeUnit.SECONDS)
|
||||
public void put(Main.ExecutionPlan plan) {
|
||||
final var client = plan.getClient();
|
||||
final var entry = plan.nextEntry();
|
||||
|
||||
final var requestBuilder = plan.newRequestBuilder(entry.getKey())
|
||||
.header("Content-Type", "application/octet-stream")
|
||||
.PUT(HttpRequest.BodyPublishers.ofByteArray(entry.getValue()));
|
||||
|
||||
final var response = client.send(requestBuilder.build(), HttpResponse.BodyHandlers.ofByteArray());
|
||||
if (201 != response.statusCode()) {
|
||||
throw new IllegalStateException(Integer.toString(response.statusCode()));
|
||||
}
|
||||
}
|
||||
}
|
1
benchmark/src/jmh/resources/benchmark.properties
Normal file
1
benchmark/src/jmh/resources/benchmark.properties
Normal file
@@ -0,0 +1 @@
|
||||
gbcs.server.url= http://localhost:8080
|
21
conf/logback.xml
Normal file
21
conf/logback.xml
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE configuration>
|
||||
|
||||
<configuration>
|
||||
<import class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"/>
|
||||
<import class="ch.qos.logback.core.ConsoleAppender"/>
|
||||
|
||||
<appender name="console" class="ConsoleAppender">
|
||||
<target>System.err</target>
|
||||
<encoder class="PatternLayoutEncoder">
|
||||
<pattern>%d [%highlight(%-5level)] \(%thread\) %logger{36} -%kvp- %msg %n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="info">
|
||||
<appender-ref ref="console"/>
|
||||
</root>
|
||||
<logger name="io.netty" level="debug"/>
|
||||
<logger name="com.google.code.yanf4j" level="warn"/>
|
||||
<logger name="net.rubyeye.xmemcached" level="warn"/>
|
||||
</configuration>
|
@@ -31,5 +31,5 @@ include 'gbcs-base'
|
||||
include 'gbcs-memcached'
|
||||
include 'gbcs-cli'
|
||||
include 'docker'
|
||||
|
||||
include 'benchmark'
|
||||
|
||||
|
@@ -190,7 +190,7 @@ class GradleBuildCacheServer(private val cfg: Configuration) {
|
||||
} else {
|
||||
val javaKeyStore = loadKeystore(keyStore.file, keyStore.password)
|
||||
val serverKey = javaKeyStore.getKey(
|
||||
keyStore.keyAlias, keyStore.keyPassword?.let(String::toCharArray)
|
||||
keyStore.keyAlias, (keyStore.keyPassword ?: "").let(String::toCharArray)
|
||||
) as PrivateKey
|
||||
val serverCert: Array<X509Certificate> =
|
||||
Arrays.stream(javaKeyStore.getCertificateChain(keyStore.keyAlias))
|
||||
|
Reference in New Issue
Block a user