diff --git a/frameworks/Java/jooby/pom.xml b/frameworks/Java/jooby/pom.xml index 2e68d6ca1b0..67d5f52fe9e 100644 --- a/frameworks/Java/jooby/pom.xml +++ b/frameworks/Java/jooby/pom.xml @@ -11,9 +11,8 @@ jooby - 2.8.8 - - 4.1.34.Final + 2.8.9 + 4.1.49.Final 42.2.13 UTF-8 1.8 @@ -67,9 +66,9 @@ - io.reactiverse - reactive-pg-client - 0.11.4 + io.vertx + vertx-pg-client + 3.9.1 diff --git a/frameworks/Java/jooby/src/main/java/com/techempower/PgClients.java b/frameworks/Java/jooby/src/main/java/com/techempower/PgClients.java index 4ca2d496df0..420507858d6 100644 --- a/frameworks/Java/jooby/src/main/java/com/techempower/PgClients.java +++ b/frameworks/Java/jooby/src/main/java/com/techempower/PgClients.java @@ -1,32 +1,42 @@ package com.techempower; -import io.reactiverse.pgclient.PgClient; -import io.reactiverse.pgclient.PgPool; -import io.reactiverse.pgclient.PgPoolOptions; +import com.typesafe.config.Config; import io.vertx.core.Vertx; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.stream.Stream; +import io.vertx.core.VertxOptions; +import io.vertx.pgclient.PgConnectOptions; +import io.vertx.pgclient.PgPool; +import io.vertx.sqlclient.PoolOptions; public class PgClients { - private final Iterator iterator; + private static final PoolOptions SINGLE = new PoolOptions().setMaxSize(1); + + private final PgConnectOptions connectOptions; + + private final Vertx vertx; + + private ThreadLocal sqlClient = ThreadLocal.withInitial(this::sqlClientPool); + + public PgClients(Config config) { + this.vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true).setWorkerPoolSize(4)); + this.connectOptions = pgPoolOptions(config); + } - private PgClients(Collection clients) { - iterator = Stream.generate(() -> clients).flatMap(Collection::stream).iterator(); + public PgPool next() { + return sqlClient.get(); } - public synchronized PgPool next() { - return iterator.next(); + private PgConnectOptions pgPoolOptions(Config config) { + PgConnectOptions options = new PgConnectOptions(); + options.setDatabase(config.getString("databaseName")); + options.setHost(config.getString("serverName")); + options.setPort(config.getInt("portNumber")); + options.setUser(config.getString("user")); + options.setPassword(config.getString("password")); + options.setCachePreparedStatements(true); + return options; } - public static PgClients create(Vertx vertx, PgPoolOptions options) { - List clients = new ArrayList<>(); - for (int i = 0; i < Runtime.getRuntime().availableProcessors(); i++) { - clients.add(PgClient.pool(vertx, options)); - } - return new PgClients(clients); + private PgPool sqlClientPool() { + return PgPool.pool(vertx, connectOptions, SINGLE); } } diff --git a/frameworks/Java/jooby/src/main/java/com/techempower/ReactivePg.java b/frameworks/Java/jooby/src/main/java/com/techempower/ReactivePg.java index 9fa9741a3e0..790b3039052 100644 --- a/frameworks/Java/jooby/src/main/java/com/techempower/ReactivePg.java +++ b/frameworks/Java/jooby/src/main/java/com/techempower/ReactivePg.java @@ -1,18 +1,13 @@ package com.techempower; import com.fasterxml.jackson.databind.ObjectMapper; -import com.typesafe.config.Config; import io.jooby.Jooby; import io.jooby.json.JacksonModule; import io.jooby.rocker.RockerModule; -import io.reactiverse.pgclient.PgClient; -import io.reactiverse.pgclient.PgConnection; -import io.reactiverse.pgclient.PgIterator; -import io.reactiverse.pgclient.PgPoolOptions; -import io.reactiverse.pgclient.Row; -import io.reactiverse.pgclient.Tuple; -import io.vertx.core.Vertx; -import io.vertx.core.VertxOptions; +import io.vertx.pgclient.PgPool; +import io.vertx.sqlclient.Row; +import io.vertx.sqlclient.RowIterator; +import io.vertx.sqlclient.Tuple; import java.io.IOException; import java.util.ArrayList; @@ -33,9 +28,7 @@ public class ReactivePg extends Jooby { { /** PG client: */ - Vertx vertx = Vertx.vertx(new VertxOptions().setPreferNativeTransport(true)); - PgPoolOptions options = pgPoolOptions(getConfig().getConfig("db")); - PgClients clients = PgClients.create(vertx, new PgPoolOptions(options).setMaxSize(1)); + PgClients clients = new PgClients(getConfig().getConfig("db")); /** Template engine: */ install(new RockerModule()); @@ -46,13 +39,14 @@ public class ReactivePg extends Jooby { /** Single query: */ get("/db", ctx -> { - clients.next().preparedQuery(SELECT_WORLD, Tuple.of(randomWorld()), rsp -> { + clients.next().preparedQuery(SELECT_WORLD).execute(Tuple.of(randomWorld()), rsp -> { try { if (rsp.succeeded()) { - PgIterator rs = rsp.result().iterator(); + RowIterator rs = rsp.result().iterator(); Row row = rs.next(); ctx.setResponseType(JSON) - .send(mapper.writeValueAsBytes(new World(row.getInteger(0), row.getInteger(1)))); + .send( + mapper.writeValueAsBytes(new World(row.getInteger(0), row.getInteger(1)))); } else { ctx.sendError(rsp.cause()); } @@ -69,11 +63,11 @@ public class ReactivePg extends Jooby { AtomicInteger counter = new AtomicInteger(); AtomicBoolean failed = new AtomicBoolean(false); World[] result = new World[queries]; - PgClient client = clients.next(); + PgPool client = clients.next(); for (int i = 0; i < result.length; i++) { - client.preparedQuery(SELECT_WORLD, Tuple.of(randomWorld()), rsp -> { + client.preparedQuery(SELECT_WORLD).execute(Tuple.of(randomWorld()), rsp -> { if (rsp.succeeded()) { - PgIterator rs = rsp.result().iterator(); + RowIterator rs = rsp.result().iterator(); Row row = rs.next(); result[counter.get()] = new World(row.getInteger(0), row.getInteger(1)); } else { @@ -101,60 +95,51 @@ public class ReactivePg extends Jooby { World[] result = new World[queries]; AtomicInteger counter = new AtomicInteger(0); AtomicBoolean failed = new AtomicBoolean(false); - clients.next().getConnection(ar -> { - if (ar.failed()) { - if (failed.compareAndSet(false, true)) { - ctx.sendError(ar.cause()); + PgPool pool = clients.next(); + for (int i = 0; i < queries; i++) { + pool.preparedQuery(SELECT_WORLD).execute(Tuple.of(randomWorld()), query -> { + if (query.succeeded()) { + RowIterator rs = query.result().iterator(); + Tuple row = rs.next(); + World world = new World(row.getInteger(0), randomWorld()); + result[counter.get()] = world; + } else { + if (failed.compareAndSet(false, true)) { + ctx.sendError(query.cause()); + return; + } } - return; - } - PgConnection conn = ar.result(); - for (int i = 0; i < queries; i++) { - conn.preparedQuery(SELECT_WORLD, Tuple.of(randomWorld()), query -> { - if (query.succeeded()) { - PgIterator rs = query.result().iterator(); - Tuple row = rs.next(); - World world = new World(row.getInteger(0), randomWorld()); - result[counter.get()] = world; - } else { - conn.close(); - if (failed.compareAndSet(false, true)) { - ctx.sendError(query.cause()); - return; - } + + if (counter.incrementAndGet() == queries && !failed.get()) { + List batch = new ArrayList<>(queries); + for (World world : result) { + batch.add(Tuple.of(world.getRandomNumber(), world.getId())); } - if (counter.incrementAndGet() == queries && !failed.get()) { - List batch = new ArrayList<>(queries); - for (World world : result) { - batch.add(Tuple.of(world.getRandomNumber(), world.getId())); - } - - conn.preparedBatch(UPDATE_WORLD, batch, update -> { - conn.close(); - if (update.failed()) { - ctx.sendError(update.cause()); - } else { - try { - ctx.setResponseType(JSON) - .send(mapper.writeValueAsBytes(result)); - } catch (IOException x) { - ctx.sendError(x); + pool.preparedQuery(UPDATE_WORLD) + .executeBatch(batch, update -> { + if (update.failed()) { + ctx.sendError(update.cause()); + } else { + try { + ctx.setResponseType(JSON) + .send(mapper.writeValueAsBytes(result)); + } catch (IOException x) { + ctx.sendError(x); + } } - } - }); - } - }); - } - }); + }); + } + }); + } return ctx; }); /** Fortunes: */ get("/fortunes", ctx -> { - clients.next().preparedQuery(SELECT_FORTUNE, rsp -> { + clients.next().preparedQuery(SELECT_FORTUNE).execute(rsp -> { if (rsp.succeeded()) { - PgIterator rs = rsp.result().iterator(); + RowIterator rs = rsp.result().iterator(); List fortunes = new ArrayList<>(); while (rs.hasNext()) { @@ -176,17 +161,6 @@ public class ReactivePg extends Jooby { }); } - private PgPoolOptions pgPoolOptions(Config config) { - PgPoolOptions options = new PgPoolOptions(); - options.setDatabase(config.getString("databaseName")); - options.setHost(config.getString("serverName")); - options.setPort(config.getInt("portNumber")); - options.setUser(config.getString("user")); - options.setPassword(config.getString("password")); - options.setCachePreparedStatements(true); - return options; - } - public static void main(String[] args) { runApp(args, EVENT_LOOP, ReactivePg::new); } diff --git a/frameworks/Kotlin/kooby/pom.xml b/frameworks/Kotlin/kooby/pom.xml index fe02c2dabe8..750bbd3a76e 100644 --- a/frameworks/Kotlin/kooby/pom.xml +++ b/frameworks/Kotlin/kooby/pom.xml @@ -12,7 +12,7 @@ kooby: jooby+kotlin - 2.8.8 + 2.8.9 42.2.13 UTF-8 1.8