I don't really get how this works - but I'd love to know. ;)Is this supposed to work with "everything" that's async right now?
What happens, when an excpetion occurs, let's say during reading a file asynchronously. Will it throw an exception just like it would if it were truly sync?
What happens with handlers that fire multiple times? Like incoming event bus handlers or server requests.
--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Hi.I work on Quasar.There's a growing number of Quasar-integrated third-party libraries here. To integrate your own (as Tim did with vert.x itself) follow the guidelines and examples here.
JDBC is integrated (as well as jOOQ and JDBI), but because there isn't an async JDBC API, a separate thread pool is used to run (and block on) the actual JDBC operations. This shouldn't really matter, though. When you use the JDBC-quasar integration, the fiber making the call (and the sync verticle multiplexes fibers onto a single thread) blocks without blocking the underlying kernel thread.
Please note that while JDBC itself is integrated, that doesn't mean any library built on top of it -- namely Hibernate or other JPA ORMs -- is. Currently, direct JDBC, jOOQ and JDBI are supported. We are working with Oracle to introduce a (very minor) change to the JVM in Java 9 that would make it so that if a low-level API (like JDBC) is integrated with Quasar, then anything built on top of it (like Hibernate) would work, too (and you won't need to mark your blocking methods with @Suspendable/throws SuspendExecution either.
What you're suggesting might well be possible (in fact, it won't even require any work) with Quasar and Java 9.
The question is how worthwhile it will be, especially considering JDBC. Blocking threads isn't bad: the OS is very, very good at waking blocked threads very quickly (although, only threads blocked on IO; not those waiting to be woken up by other threads). This is why blocking IO has lower latency than async IO. The problem with blocking threads is one of throughput and scale: the OS is not good at scheduling lots and lots of threads or threads that block very often. So it really shouldn't bother you -- neither should you try to optimize -- a pool of, say, 10 threads that blocks on JDBC. Your database is likelier to hit its limits long before blocking those few threads would have any negative impact on your server. You should be worried about blocking if you're using an in-memory database/cache or anything else that can operate at very high throughput.
There's nothing we can do about latency (async IO makes it a little worse, in fact); what we're trying to increase is throughput (while maintaining reasonable latency), so the question of how important is not blocking kernel threads, depends on the throughput potentially offered by the API. JDBC usually offers relatively low throughput, so blocking kernel threads is probably good enough to make async not worthwhile.
What you're suggesting might well be possible (in fact, it won't even require any work) with Quasar and Java 9.
Gladly -- but only once Oracle fully approves the change...
private CompletableFuture<JsonArray> doProjectSearch(JsonObject postBody, TestContext context) {
HttpClientRequest postReq = deployment.httpClient().post(deployment.httpPort(), deployment.httpHost(), "/api/2/projects-search");
CompletableFuture<HttpClientResponse> postReqCF = Promisify.promisify(postReq);
postReq.end(postBody.encode());
Async async1 = context.async();
return postReqCF.thenCompose((HttpClientResponse resp) ->
Promisify.readHttpResponseBodyAsFuture(resp).thenApply((Buffer body) -> {
JsonArray data = new JsonArray(body.toString());
async1.complete();
return data;
})
);
}
public static CompletableFuture<HttpClientResponse> promisify(HttpClientRequest request) {
CompletableFuture<HttpClientResponse> cf = new CompletableFuture<>();
request.handler(cf::complete);
request.exceptionHandler(cf::completeExceptionally);
return cf;
}
public static CompletableFuture<Buffer> readHttpResponseBodyAsFuture(HttpClientResponse response) {
CompletableFuture<Buffer> cf = new CompletableFuture<>();
response.bodyHandler(cf::complete);
response.exceptionHandler(cf::completeExceptionally);
return cf;
}