33A lightweight wrapper to the [ JDK 11+ Java Http Client] ( http://openjdk.java.net/groups/net/httpclient/intro.html )
44
55- Use Java 11.0.8 or higher (some SSL related bugs prior to 11.0.8 with JDK HttpClient)
6- - Adds a fluid API for request constructing URL and payload
6+ - Adds a fluid API for building URL and payload
77- Adds JSON marshalling/unmarshalling of request and response using Jackson or Gson
88- Gzip encoding/decoding
99- Logging of request/response logging
@@ -18,7 +18,7 @@ A lightweight wrapper to the [JDK 11+ Java Http Client](http://openjdk.java.net/
1818<dependency >
1919 <groupId >io.avaje</groupId >
2020 <artifactId >avaje-http-client</artifactId >
21- <version >1.7 </version >
21+ <version >1.9 </version >
2222</dependency >
2323```
2424
@@ -495,8 +495,15 @@ obtained for initial request and then renewed when the token has expired.
495495The following is a very quick and rough comparison of running 10,000 requests
496496using ` Async ` vs ` Loom ` .
497497
498- To run this test myself I use [ Jex] ( https://github.com/avaje/avaje-jex ) as the
499- server (Jetty based) and have it running using Loom.
498+ The intention is to test the thought that in a "future Loom world" the
499+ desire to use ` async() ` execution with HttpClient reduces.
500+
501+ TLDR: Caveat, caveat, more caveats ... initial testing shows Loom to be just a
502+ touch faster (~ 10%) than async.
503+
504+ To run my tests I use [ Jex] ( https://github.com/avaje/avaje-jex ) as the server
505+ (Jetty based) and have it running using Loom. For whatever testing you do
506+ you will need a server that can handle a very large number of concurrent requests.
500507
501508The Loom blocking request (make 10K of these)
502509
@@ -527,72 +534,74 @@ HttpClient's reactive streams. The `whenComplete()` callback is invoked
527534when the response is ready. Collect all the resulting CompletableFuture
528535and wait for them all to complete.
529536
537+ Outline:
538+
530539``` java
531540
532541// Collect all the CompletableFuture's
533- List<CompletableFuture<HttpResponse<String > > > all = new ArrayList<> ();
542+ List<CompletableFuture<HttpResponse<String > > > futures = new ArrayList<> ();
534543
535- long start = System . currentTimeMillis();
536544for (int i = 0 ; i < 10_000 ; i++ ) {
537- all. add(httpClient. request(). path(" s200" )
538- . GET ()
539- .async(). asString()
540- .whenComplete((hres, throwable) - > {
541- output(hres);
542- }));
545+ futures. add(httpClient. request(). path(" s200" )
546+ . GET ()
547+ .async(). asString()
548+ .whenComplete((hres, throwable) - > {
549+ // confirm 200 response etc
550+ ...
551+ }));
543552}
544553
545- // wait for them all to complete ..
546- CompletableFuture . allOf(all. toArray(new CompletableFuture [0 ]))
547- .join();
554+ // wait for all requests to complete via join() ...
555+ CompletableFuture . allOf(futures. toArray(new CompletableFuture [0 ])). join();
548556
549- long exeMs = System . currentTimeMillis() - start;
550- System . out. println(" Complete ... exeMillis:" + exeMs);
551557```
552- Runs is approx 5 to 5.5 seconds on my environment (without sout).
553558
554559### 10K requests using Loom
555560
556561With Loom Java 17 EA Release we can use ` Executors.newVirtualThreadExecutor() `
557- to return an ExecutorService that uses Loom Virtual Threads. These
558- are backed by "Carrier threads" (via ForkedJoinPool).
562+ to return an ExecutorService that uses Loom Virtual Threads. These are backed
563+ by "Carrier threads" (via ForkedJoinPool).
559564
560- ``` java
565+ Outline:
561566
562- long start = System . currentTimeMillis();
567+ ``` java
563568
564- // Use Loom's Executors.newVirtualThreadExecutor()
569+ // use Loom's Executors.newVirtualThreadExecutor()
565570
566571try (ExecutorService executorService = Executors . newVirtualThreadExecutor()) {
567572 for (int i = 0 ; i < 10_000 ; i++ ) {
568573 executorService. submit(this :: task);
569574 }
570575}
571576
572- long exeMs = System . currentTimeMillis() - start;
573- System . out. println(" Complete ... exeMillis:" + exeMs);
574577```
575578``` java
576579private void task() {
577- HttpResponse<String > hres = performGet();
578- System . out. println(" status:" + hres. statusCode() + " length:" + hres. body(). length());
579- }
580+ HttpResponse<String > hres =
581+ httpClient. request(). path(" s200" )
582+ . GET ()
583+ .asString();
580584
581- private HttpResponse<String > performGet() {
582- return httpClient. request()
583- .path(" s200" )
584- . GET ()
585- .asString();
585+ // confirm 200 response etc
586+ ...
586587}
588+
587589```
588590
589- Running in approx 4.5 to 5 seconds on my environment (without sout).
591+ Caveat: Proper performance benchmarks are really hard and take a lot of
592+ effort.
593+
594+ Running some "rough/approx performance comparison tests" using ` Loom `
595+ build ` 17 EA 2021-09-14 / (build 17-loom+7-342) ` vs ` Async ` for my environment
596+ and 10K request scenarios has loom execution around 10% faster than async.
597+
598+ It looks like Loom and Async run in pretty much the same time although it
599+ currently looks that Loom is just a touch faster (perhaps due to how it does
600+ park/unpark). More investigation required.
590601
591- It looks like Loom and Async run in pretty much the same time although
592- it could be that Loom is just a slight touch faster. I need to do more
593- investigation.
594602
595- Build used is: ` 17 EA 2021-09-14 / (build 17-loom+7-342) ` .
603+ Date: 2021-06
604+ Build: ` 17 EA 2021-09-14 / (build 17-loom+7-342) ` .
596605
597606```
598607openjdk version "17-loom" 2021-09-14
0 commit comments