Recently, for a Rusty Web
It’s been a few months since I shifted my focus full time to Rust, and in that time, we’ve gotten a lot of work done! I wanted to update you here what all that is, since it’s spread around on multiple repositories.
We started working on the http crate earlier last year, but in September, we released v0.1! The point of this crate was pull out the “HTTP primitives”, like headers, methods, status codes, and the like, and put them into a base crate. The hope is that HTTP implementations can expose APIs using these types, and web frameworks can expect them, and thus more easily change implementations if so desired.
Since then, we’ve seen several implementations already put them to good use:
At Buoyant, one of the products we build is Conduit, a service-mesh slash proxy built for Kubernetes environments, requiring minimal setup. The proxy part (“data plane”) is built in Rust. Since many internal services take advantage of HTTP2, we needed a working HTTP2 implementation in Rust. So, we built one! After building and using it in Conduit, we eventually got it to a v0.1 release of h2.
Importantly, it’s fast, implements the full HTTP2 specification, and works with asynchronous IO and futures.
Tower and gRPC
Besides an HTTP2 implementation, we also needed use gRPC to have the proxy talk with the controller. We built up a middleware suite, tower, which needs its own announcement when it’s released, but in short, is an evolution of tokio-service, sort of like finagle for Rust. Once we had several
Services working, we got to work on tower-grpc, which merges together tower, the h2 crate, and protobuf to get elegant code generation speaking gRPC.
Besides all those awesome things, the hyper crate has continued to see increased development. Since September, hyper has seen 16 point releases, bringing bug fixes, performance improvements, and new features! Some highlights:
- hyper got even faster. Besides bug fixes and new features, hyper managed to get even faster than before, as shown in these benchmarks. Admittedly, microbenchmarks need to be considered with plenty of salt, but it ain’t nothing! Besides the microbenchmark, hyper also improvement throughput for bigger streaming bodies by intelligently using
writevwhen it can (it also detects if
writevisn’t helping, and reverts to previous behavior).
Added APIs to create servers with a shared tokio
Core. The easy entry point to running a server in hyper is using
Http::bind, which creates a
Serverwith its own
Core. However, as applications get more complex, you may want to use the same
Corefor multiple things. Several APIs were added to allow doing just that:
- Removed dependence on tokio-proto. The
tokio-protocrate was initially used internally, but it hasn’t seen many updates, and it was found to be buggy. hyper was suffering from those bugs, as well as not being able to improve the exposed API. A bunch of work was done to build an internal dispatcher, removing the need to rely on tokio-proto, and fixing a bunch of bugs in the process.
- Added compatibility with the
httpcrate. Completely switching the HTTP types to those from the
httpcrate is a breaking change, but to allow usage incrementally, you can opt-in to using them by enabling the Cargo
compatfeature of hyper. In 0.12, they will be completely replaced.