|
@@ -1,15 +1,13 @@
|
|
package com.techempower;
|
|
package com.techempower;
|
|
|
|
|
|
|
|
+import static com.techempower.Util.boxedRandomWorld;
|
|
import static com.techempower.Util.randomWorld;
|
|
import static com.techempower.Util.randomWorld;
|
|
import static io.jooby.ExecutionMode.EVENT_LOOP;
|
|
import static io.jooby.ExecutionMode.EVENT_LOOP;
|
|
import static io.jooby.MediaType.JSON;
|
|
import static io.jooby.MediaType.JSON;
|
|
|
|
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
|
|
-import com.fizzed.rocker.RockerOutputFactory;
|
|
|
|
-import com.techempower.rocker.BufferRockerOutput;
|
|
|
|
import io.jooby.*;
|
|
import io.jooby.*;
|
|
-import io.jooby.rocker.DataBufferOutput;
|
|
|
|
import io.jooby.rocker.RockerModule;
|
|
import io.jooby.rocker.RockerModule;
|
|
import io.vertx.sqlclient.Row;
|
|
import io.vertx.sqlclient.Row;
|
|
import io.vertx.sqlclient.RowIterator;
|
|
import io.vertx.sqlclient.RowIterator;
|
|
@@ -17,22 +15,16 @@ import io.vertx.sqlclient.Tuple;
|
|
|
|
|
|
public class ReactivePg extends Jooby {
|
|
public class ReactivePg extends Jooby {
|
|
{
|
|
{
|
|
- /** Reduce the number of resources due we do reactive processing. */
|
|
|
|
- setServerOptions(
|
|
|
|
- new ServerOptions()
|
|
|
|
- .setIoThreads(Runtime.getRuntime().availableProcessors() + 1)
|
|
|
|
- .setWorkerThreads(Runtime.getRuntime().availableProcessors() + 1)
|
|
|
|
- );
|
|
|
|
-
|
|
|
|
/** PG client: */
|
|
/** PG client: */
|
|
PgClient client = new PgClient(getConfig().getConfig("db"));
|
|
PgClient client = new PgClient(getConfig().getConfig("db"));
|
|
|
|
|
|
/** Template engine: */
|
|
/** Template engine: */
|
|
install(new RockerModule());
|
|
install(new RockerModule());
|
|
|
|
+ Json.configure(getOutputFactory());
|
|
|
|
|
|
/** Single query: */
|
|
/** Single query: */
|
|
get("/db", ctx -> {
|
|
get("/db", ctx -> {
|
|
- client.selectWorld(Tuple.of(randomWorld()), rsp -> {
|
|
|
|
|
|
+ client.selectWorld(Tuple.of(boxedRandomWorld()), rsp -> {
|
|
if (rsp.succeeded()) {
|
|
if (rsp.succeeded()) {
|
|
RowIterator<Row> rs = rsp.result().iterator();
|
|
RowIterator<Row> rs = rsp.result().iterator();
|
|
Row row = rs.next();
|
|
Row row = rs.next();
|
|
@@ -43,7 +35,7 @@ public class ReactivePg extends Jooby {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
return ctx;
|
|
return ctx;
|
|
- }).setNonBlocking(true);
|
|
|
|
|
|
+ });
|
|
|
|
|
|
/** Multiple queries: */
|
|
/** Multiple queries: */
|
|
get("/queries", ctx -> {
|
|
get("/queries", ctx -> {
|
|
@@ -64,24 +56,24 @@ public class ReactivePg extends Jooby {
|
|
}
|
|
}
|
|
});
|
|
});
|
|
return ctx;
|
|
return ctx;
|
|
- }).setNonBlocking(true);
|
|
|
|
|
|
+ });
|
|
|
|
|
|
/** Update queries: */
|
|
/** Update queries: */
|
|
get("/updates", ctx -> {
|
|
get("/updates", ctx -> {
|
|
int queries = Util.queries(ctx);
|
|
int queries = Util.queries(ctx);
|
|
World[] result = new World[queries];
|
|
World[] result = new World[queries];
|
|
- client.selectWorldForUpdate(queries, (index, statement) -> {
|
|
|
|
- int id = randomWorld();
|
|
|
|
- statement.execute(Tuple.of(id), selectCallback -> {
|
|
|
|
- if (selectCallback.failed()) {
|
|
|
|
- sendError(ctx, selectCallback.cause());
|
|
|
|
|
|
+ var updater = client.updater();
|
|
|
|
+ updater.selectWorldForUpdate(queries, (index, statement) -> {
|
|
|
|
+ statement.execute(Tuple.of(boxedRandomWorld())).onComplete(rsp -> {
|
|
|
|
+ if (rsp.failed()) {
|
|
|
|
+ sendError(ctx, rsp.cause());
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
result[index] = new World(
|
|
result[index] = new World(
|
|
- selectCallback.result().iterator().next().getInteger(0),
|
|
|
|
- randomWorld());
|
|
|
|
|
|
+ rsp.result().iterator().next().getInteger(0),
|
|
|
|
+ boxedRandomWorld());
|
|
if (index == queries - 1) {
|
|
if (index == queries - 1) {
|
|
- client.updateWorld(result, updateCallback -> {
|
|
|
|
|
|
+ updater.updateWorld(result, updateCallback -> {
|
|
if (updateCallback.failed()) {
|
|
if (updateCallback.failed()) {
|
|
sendError(ctx, updateCallback.cause());
|
|
sendError(ctx, updateCallback.cause());
|
|
} else {
|
|
} else {
|
|
@@ -93,10 +85,9 @@ public class ReactivePg extends Jooby {
|
|
});
|
|
});
|
|
});
|
|
});
|
|
return ctx;
|
|
return ctx;
|
|
- }).setNonBlocking(true);
|
|
|
|
|
|
+ });
|
|
|
|
|
|
/** Fortunes: */
|
|
/** Fortunes: */
|
|
- var factory = BufferRockerOutput.factory();
|
|
|
|
get("/fortunes", ctx -> {
|
|
get("/fortunes", ctx -> {
|
|
client.fortunes(rsp -> {
|
|
client.fortunes(rsp -> {
|
|
if (rsp.succeeded()) {
|
|
if (rsp.succeeded()) {
|
|
@@ -112,15 +103,14 @@ public class ReactivePg extends Jooby {
|
|
Collections.sort(fortunes);
|
|
Collections.sort(fortunes);
|
|
|
|
|
|
/** render view: */
|
|
/** render view: */
|
|
- views.fortunes template = views.fortunes.template(fortunes);
|
|
|
|
ctx.setResponseType(MediaType.html)
|
|
ctx.setResponseType(MediaType.html)
|
|
- .send(template.render(factory).toBuffer());
|
|
|
|
|
|
+ .render(views.fortunes.template(fortunes));
|
|
} else {
|
|
} else {
|
|
sendError(ctx, rsp.cause());
|
|
sendError(ctx, rsp.cause());
|
|
}
|
|
}
|
|
});
|
|
});
|
|
return ctx;
|
|
return ctx;
|
|
- }).setNonBlocking(true);
|
|
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
private void sendError(Context ctx, Throwable cause) {
|
|
private void sendError(Context ctx, Throwable cause) {
|