diff --git a/frameworks/quarkus-jvm/pom.xml b/frameworks/quarkus-jvm/pom.xml index e6298136..9dae1152 100644 --- a/frameworks/quarkus-jvm/pom.xml +++ b/frameworks/quarkus-jvm/pom.xml @@ -2,6 +2,7 @@ + 4.0.0 com.httparena @@ -39,17 +40,17 @@ org.xerial sqlite-jdbc - 3.47.2.0 + 3.51.3.0 org.postgresql postgresql - 42.7.4 + 42.7.10 com.zaxxer HikariCP - 6.2.1 + 7.0.2 @@ -70,4 +71,5 @@ + diff --git a/frameworks/quarkus-jvm/src/main/java/com/httparena/BenchmarkResource.java b/frameworks/quarkus-jvm/src/main/java/com/httparena/BenchmarkResource.java index 813e3671..41cc2087 100644 --- a/frameworks/quarkus-jvm/src/main/java/com/httparena/BenchmarkResource.java +++ b/frameworks/quarkus-jvm/src/main/java/com/httparena/BenchmarkResource.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import io.smallrye.common.annotation.NonBlocking; -import io.vertx.core.buffer.Buffer; import jakarta.annotation.PostConstruct; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; @@ -14,21 +13,17 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.net.URI; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; @Path("/") public class BenchmarkResource { - private static final Buffer OK_BUFFER = Buffer.buffer("ok".getBytes(StandardCharsets.UTF_8)); - private final ObjectMapper mapper = new ObjectMapper(); private List> dataset; private byte[] largeJsonResponse; @@ -38,16 +33,6 @@ public class BenchmarkResource { private static final ThreadLocal tlConn = new ThreadLocal<>(); private static final ThreadLocal tlStmt = new ThreadLocal<>(); private HikariDataSource pgPool; - private final Map staticFiles = new ConcurrentHashMap<>(); - private static final Map MIME_TYPES = Map.ofEntries( - Map.entry(".css", "text/css"), - Map.entry(".js", "application/javascript"), - Map.entry(".html", "text/html"), - Map.entry(".woff2", "font/woff2"), - Map.entry(".svg", "image/svg+xml"), - Map.entry(".webp", "image/webp"), - Map.entry(".json", "application/json") - ); @PostConstruct public void init() throws IOException { @@ -98,36 +83,22 @@ public void init() throws IOException { pgPool = new HikariDataSource(config); } catch (Exception ignored) {} } - // Pre-load static files - File staticDir = new File("/data/static"); - if (staticDir.isDirectory()) { - File[] files = staticDir.listFiles(); - if (files != null) { - for (File sf : files) { - if (sf.isFile()) { - try { - staticFiles.put(sf.getName(), Files.readAllBytes(sf.toPath())); - } catch (IOException ignored) {} - } - } - } - } } @GET @Path("/pipeline") @Produces(MediaType.TEXT_PLAIN) @NonBlocking - public Buffer pipeline() { - return OK_BUFFER; + public String pipeline() { + return "ok"; } @GET @Path("/baseline11") @Produces(MediaType.TEXT_PLAIN) @NonBlocking - public String baselineGet(@QueryParam("a") String a, @QueryParam("b") String b) { - return String.valueOf(sumParams(a, b)); + public int baselineGet(@QueryParam("a") int a, @QueryParam("b") int b) { + return a + b; } @POST @@ -135,33 +106,24 @@ public String baselineGet(@QueryParam("a") String a, @QueryParam("b") String b) @Consumes(MediaType.TEXT_PLAIN) @Produces(MediaType.TEXT_PLAIN) @NonBlocking - public String baselinePost(@QueryParam("a") String a, @QueryParam("b") String b, String body) { - int sum = sumParams(a, b); - try { - sum += Integer.parseInt(body.trim()); - } catch (NumberFormatException ignored) {} - return String.valueOf(sum); + public int baselinePost(@QueryParam("a") int a, @QueryParam("b") int b, int body) { + return a + b + body; } @POST @Path("/upload") + @Consumes(MediaType.APPLICATION_OCTET_STREAM) @Produces(MediaType.TEXT_PLAIN) - public String upload(InputStream body) throws IOException { - byte[] buf = new byte[65536]; - long total = 0; - int n; - while ((n = body.read(buf)) != -1) { - total += n; - } - return String.valueOf(total); + public long upload(InputStream body) throws IOException { + return body.transferTo(OutputStream.nullOutputStream()); } @GET @Path("/baseline2") @Produces(MediaType.TEXT_PLAIN) @NonBlocking - public String baseline2(@QueryParam("a") String a, @QueryParam("b") String b) { - return String.valueOf(sumParams(a, b)); + public int baseline2(@QueryParam("a") int a, @QueryParam("b") int b) { + return a + b; } @GET @@ -268,20 +230,6 @@ public byte[] compression() { return largeJsonResponse; } - @GET - @Path("/static/{filename}") - @NonBlocking - public jakarta.ws.rs.core.Response staticFile(@PathParam("filename") String filename) { - byte[] data = staticFiles.get(filename); - if (data == null) { - return jakarta.ws.rs.core.Response.status(404).build(); - } - int dot = filename.lastIndexOf('.'); - String ext = dot >= 0 ? filename.substring(dot) : ""; - String ct = MIME_TYPES.getOrDefault(ext, "application/octet-stream"); - return jakarta.ws.rs.core.Response.ok(data).header("Content-Type", ct).build(); - } - private PreparedStatement getDbStmt() { PreparedStatement stmt = tlStmt.get(); if (stmt != null) return stmt; @@ -297,10 +245,4 @@ private PreparedStatement getDbStmt() { return stmt; } - private int sumParams(String a, String b) { - int sum = 0; - if (a != null) try { sum += Integer.parseInt(a); } catch (NumberFormatException ignored) {} - if (b != null) try { sum += Integer.parseInt(b); } catch (NumberFormatException ignored) {} - return sum; - } } diff --git a/frameworks/quarkus-jvm/src/main/java/com/httparena/StaticFiles.java b/frameworks/quarkus-jvm/src/main/java/com/httparena/StaticFiles.java new file mode 100644 index 00000000..46ee9dcf --- /dev/null +++ b/frameworks/quarkus-jvm/src/main/java/com/httparena/StaticFiles.java @@ -0,0 +1,24 @@ +package com.httparena; + +import io.vertx.ext.web.Router; +import io.vertx.ext.web.handler.FileSystemAccess; +import io.vertx.ext.web.handler.StaticHandler; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.enterprise.event.Observes; + +/** + * Serves the static resources in /data/static + * Recommended way to do in production workloads (besides using a nginx sidecar). + */ +@ApplicationScoped +public class StaticFiles { + + void init(@Observes Router router) { + var handler = StaticHandler.create(FileSystemAccess.ROOT, "/data/static"); + + router.route("/static/*") + .handler(handler); + } + +} diff --git a/frameworks/quarkus-jvm/src/main/resources/application.properties b/frameworks/quarkus-jvm/src/main/resources/application.properties index 81e9eaf2..cc32d6b6 100644 --- a/frameworks/quarkus-jvm/src/main/resources/application.properties +++ b/frameworks/quarkus-jvm/src/main/resources/application.properties @@ -12,9 +12,11 @@ quarkus.http.ssl.client-auth=none # Allow 25MB request bodies for upload test quarkus.http.limits.max-body-size=25M +# Compression +quarkus.http.enable-compression=true + # TechEmpower-style tuning quarkus.http.accept-backlog=-1 -quarkus.http.idle-timeout=0 +quarkus.http.idle-timeout=30s quarkus.vertx.prefer-native-transport=true -quarkus.http.enable-compression=true quarkus.http.compression-level=1