Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion frameworks/Java/helidon/nima/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>io.helidon.applications</groupId>
<artifactId>helidon-se</artifactId>
<version>4.0.3</version>
<version>4.1.2</version>
<relativePath/>
</parent>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package io.helidon.benchmark.nima;

import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import java.util.List;

import com.jsoniter.output.JsonStream;
import com.jsoniter.output.JsonStreamPool;
import com.jsoniter.spi.JsonException;

public class JsonSerializer {

private JsonSerializer() {
}

/**
* Serialize an instance into a JSON object and return it as a byte array.
*
* @param obj the instance
* @return the byte array
*/
public static byte[] serialize(Object obj) {
JsonStream stream = JsonStreamPool.borrowJsonStream();
try {
stream.reset(null);
stream.writeVal(obj.getClass(), obj);
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
} catch (IOException e) {
throw new JsonException(e);
} finally {
JsonStreamPool.returnJsonStream(stream);
}
}

/**
* Serialize a map of strings into a JSON object and return it as a byte array.
*
* @param map the map
* @return the byte array
*/
public static byte[] serialize(Map<String, String> map) {
JsonStream stream = JsonStreamPool.borrowJsonStream();
try {
stream.reset(null);
stream.writeObjectStart();
map.forEach((k, v) -> {
try {
stream.writeObjectField(k);
stream.writeVal(v);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
stream.writeObjectEnd();
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
} catch (IOException e) {
throw new JsonException(e);
} finally {
JsonStreamPool.returnJsonStream(stream);
}
}

/**
* Serialize a list of objects into a JSON array and return it as a byte array.
*
* @param objs the list of objects
* @return the byte array
*/
public static byte[] serialize(List<?> objs) {
JsonStream stream = JsonStreamPool.borrowJsonStream();
try {
stream.reset(null);
stream.writeArrayStart();
int i = 0;
int n = objs.size();
for (Object obj : objs) {
stream.writeVal(obj.getClass(), obj);
if (i++ < n - 1) {
stream.writeMore();
}

}
stream.writeArrayEnd();
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
} catch (IOException e) {
throw new JsonException(e);
} finally {
JsonStreamPool.returnJsonStream(stream);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,9 @@

package io.helidon.benchmark.nima;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.logging.Logger;

import com.jsoniter.output.JsonStream;
import com.jsoniter.output.JsonStreamPool;
import com.jsoniter.spi.JsonException;
import io.helidon.benchmark.nima.models.DbRepository;
import io.helidon.benchmark.nima.models.HikariJdbcRepository;
import io.helidon.benchmark.nima.models.PgClientRepository;
Expand All @@ -41,6 +36,8 @@
import io.helidon.webserver.http.ServerRequest;
import io.helidon.webserver.http.ServerResponse;

import static io.helidon.benchmark.nima.JsonSerializer.serialize;

/**
* Main class of the benchmark.
* Opens server on localhost:8080 and exposes {@code /plaintext} and {@code /json} endpoints adhering to the
Expand Down Expand Up @@ -90,29 +87,14 @@ static void routing(HttpRules rules) {

rules.get("/plaintext", new PlaintextHandler())
.get("/json", new JsonHandler())
.get("/10k", new JsonKHandler(10))
.get("/fortunes", new FortuneHandler(repository))
.register("/", new DbService(repository));
}

private static byte[] serializeMsg(Message obj) {
JsonStream stream = JsonStreamPool.borrowJsonStream();
try {
stream.reset(null);
stream.writeVal(Message.class, obj);
return Arrays.copyOfRange(stream.buffer().data(), 0, stream.buffer().tail());
} catch (IOException e) {
throw new JsonException(e);
} finally {
JsonStreamPool.returnJsonStream(stream);
}
}

static class PlaintextHandler implements Handler {
static final Header CONTENT_TYPE = HeaderValues.createCached(HeaderNames.CONTENT_TYPE,
"text/plain; charset=UTF-8");
"text/plain; charset=UTF-8");
static final Header CONTENT_LENGTH = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH, "13");

private static final byte[] RESPONSE_BYTES = "Hello, World!".getBytes(StandardCharsets.UTF_8);

@Override
Expand All @@ -126,44 +108,16 @@ public void handle(ServerRequest req, ServerResponse res) {

static class JsonHandler implements Handler {
private static final String MESSAGE = "Hello, World!";
private static final int JSON_LENGTH = serializeMsg(new Message(MESSAGE)).length;
private static final int JSON_LENGTH = serialize(new Message(MESSAGE)).length;
static final Header CONTENT_LENGTH = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH,
String.valueOf(JSON_LENGTH));
String.valueOf(JSON_LENGTH));

@Override
public void handle(ServerRequest req, ServerResponse res) {
res.header(CONTENT_LENGTH);
res.header(HeaderValues.CONTENT_TYPE_JSON);
res.header(Main.SERVER);
res.send(serializeMsg(newMsg()));
}

private static Message newMsg() {
return new Message("Hello, World!");
}
}

static class JsonKHandler implements Handler {
private final Header contentLength;
private final String message;

JsonKHandler(int kilobytes) {
this.message = "a".repeat(1024 * kilobytes);
int length = serializeMsg(new Message(message)).length;
this.contentLength = HeaderValues.createCached(HeaderNames.CONTENT_LENGTH,
String.valueOf(length));
}

@Override
public void handle(ServerRequest req, ServerResponse res) {
res.header(contentLength);
res.header(HeaderValues.CONTENT_TYPE_JSON);
res.header(Main.SERVER);
res.send(serializeMsg(newMsg()));
}

private Message newMsg() {
return new Message(message);
res.send(serialize(new Message(MESSAGE)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,16 @@
import java.util.concurrent.ThreadLocalRandom;

import jakarta.json.Json;
import jakarta.json.JsonArray;
import jakarta.json.JsonArrayBuilder;
import jakarta.json.JsonBuilderFactory;
import jakarta.json.JsonObject;

public interface DbRepository {

JsonBuilderFactory JSON = Json.createBuilderFactory(Collections.emptyMap());

default World getWorld() {
return getWorld(randomWorldNumber());
}

World getWorld(int id);

default JsonObject getWorldAsJson(int id) {
return getWorld().toJson();
}

List<World> getWorlds(int count);

default JsonArray getWorldsAsJson(int count) {
JsonArrayBuilder result = JSON.createArrayBuilder();
for (World world : getWorlds(count)) {
result.add(world.toJson());
}
return result.build();
}

World updateWorld(World world);

List<World> updateWorlds(int count);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Logger;

import com.zaxxer.hikari.HikariConfig;
Expand All @@ -22,20 +24,31 @@ public class HikariJdbcRepository implements DbRepository {
private final HikariConfig hikariConfig;

public HikariJdbcRepository(Config config) {
// hikari connection configuration
String url = "jdbc:postgresql://" +
config.get("host").asString().orElse("tfb-database") +
":" + config.get("port").asString().orElse("5432") +
"/" + config.get("db").asString().orElse("hello_world");

hikariConfig = new HikariConfig();
hikariConfig.setJdbcUrl(url);
hikariConfig.setUsername(config.get("username").asString().orElse("benchmarkdbuser"));
hikariConfig.setPassword(config.get("password").asString().orElse("benchmarkdbpass"));
hikariConfig.addDataSourceProperty("cachePrepStmts", "true");

// hikari additional configuration
int poolSize = config.get("sql-pool-size").asInt().orElse(64);
hikariConfig.addDataSourceProperty("maximumPoolSize", poolSize);
LOGGER.info("Db pool size is set to " + poolSize);
hikariConfig.setMaximumPoolSize(poolSize);
LOGGER.info("Hikari pool size is set to " + poolSize);
ThreadFactory vtThreadFactory = Thread.ofVirtual().factory();
hikariConfig.setThreadFactory(vtThreadFactory);
hikariConfig.setScheduledExecutor(Executors.newScheduledThreadPool(poolSize, vtThreadFactory));
LOGGER.info("Set thread factory to VTs");

// data source properties
hikariConfig.addDataSourceProperty("cachePrepStmts","true");
hikariConfig.addDataSourceProperty("prepStmtCacheSize","250");
hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit","2048");
hikariConfig.addDataSourceProperty("ssl", "false");
hikariConfig.addDataSourceProperty("tcpKeepAlive", "true");
}

private Connection getConnection() throws SQLException {
Expand Down
Loading
Loading