We recently released release candidates for Gatling 3: we wrote a blog post about all the new features, read it here! If you missed them, you will find posts about the support of closed workload model and new feeders features. Today, we will talk about our new HTTP Client for Gatling 3!
Parting Ways with AsyncHttpClient
When I created Gatling 7 years ago, I was looking for a Java library implemened to top of Netty that was really non blocking at its core. AsyncHttpClient (AHC) was exactly that (kudos to Jean-François Arcand!).
At some point, I took over as the core maintainer and I believe it both benefited both projects: AHC was actively maintained and benefited from performance improvements because it was used as Gatling foundation, and Gatling benefited from feedback and contributions from a project with a larger user base.
Then, at some point, I realized things were not as simple:
- I need to implement features for Gatling very quickly. Those features could sometimes be very specific and wouldn’t be used by most regular AHC users, making API look overbloated. Sometimes, implementing those features required breaking API, while on the contrary, most AHC users needed API stability.
- Gatling was using maybe only 50% of the features in AHC. Sometimes, those features were just “getting in the way” when I wanted to implement low level features that would be pretty specific to Gatling.
When we from Gatling Corp decided to implement HTTP/2 support for Gatling 3, we realized that the current AHC code base was not suited, and that we had no idea what a generic HTTP/2 client API should look like, while we had a pretty good idea about what we wanted for Gatling.
A brand new internal HTTP client
The natural yet difficult decision was to go with implementing a new HTTP client mostly from scratch (we reused some helpers from AHC that I has implemented over the years).
This client is not a public library. It’s intended for internal Gatling usage only, so we can break things any time we want if we realize we were wrong with our design choices.
This new client leverages one of the most complex thing in AHC implementation: concurrency. In AHC, requests can be generated from some thread (outside Netty) while response chunks will be processed from Netty eventloop threads while timeouts will be triggered from a different dedicated threads. This results in very complex concurrency handling that could cause weird bugs in old Gatling version such as virtual users being lost and simulation not terminating.
With this new client, virtual users have affinity with a Netty eventloop and all their HTTP events (sending requests, handling response chunks, timeouts) will be processed in the same thread. No more concurrency issues!
We hope to be able to generalize this concept of eventloop affinity to the rest of Gatling in a future version.
BoringSSL support enabled by default
For better performance, the new client uses by default netty-tcnative and its native SSLEngine implementation instead of the default one from the JDK.
BoringSSL is Google’s fork of OpenSSL.
Coming up next week: a blog post about HTTP/2, by Alexandre Chaouat! Stay tuned!
Stephane from the Gatling team