Grpc-mojo: gRPC implemented in pure Mojo, verified against grpcio

Hi all,

Over the last while I’ve been building grpc-mojo, a gRPC implementation written entirely in Mojo, and I just made it public. It’s split across four repos:

  • mojo-net: blocking TCP/UDP sockets, DNS, IPv4/IPv6 over libc FFI (stdlib only)
  • protomojo: protobuf wire format, runtime, and a protoc plugin that generates Mojo
  • mojo-http2: HPACK and HTTP/2, including the rapid-reset style abuse guards
  • grpc-mojo: the gRPC layer itself. All four RPC kinds, deadlines, cancellation, ascii and binary metadata, the rich error model, and generated client/server stubs.

I didn’t want “my tests pass” correctness, so nothing in the project grades its own homework. The official gRPC interop cases run against grpcio in both directions (24/24 passing), h2spec passes all 146 checks, and Google’s protobuf conformance suite passes 698/698 binary wire format tests. There’s also a differential suite (52 checks against Python protobuf, python-hpack, a strict hyper-h2 peer, CPython sockets, and grpcio) that reruns on every CI push. The report it generates is published here: compliance report. Each package repo runs its own slice of the suite standalone and publishes its own report.

What it can’t do yet, mostly because Mojo 1.0 can’t: no TLS (h2c cleartext only), the server is single threaded, and there’s no compression (needs a zlib binding). That’s part of why it’s split into packages, since each piece can be reused or upstreamed on its own. mojo-net in particular started feeling like a std.net prototype while I was writing it. I’m planning a separate RFC thread on that, and I’d love to compare notes with the Lightbug folks since they’ve been down the sockets-over-FFI road already.

Fun side effect: this work shook out a compiler bug where composed integer casts sign-extend when they should zero-extend (modular/modular#6935). My own tests were happily passing, only the differential testing caught it.

Everything is Apache 2.0. Feedback, issues, and PRs are all welcome.

(Standard note: this is an independent community project, not an official gRPC project and not affiliated with Modular.)

Nice job! also all should be supported in flare already and more.

That’s awesome!! I hadn’t seen Flare yet, let me take a look!

You just can’t wait for the native async support in Mojo hein?

async isn’t strictly needed to get going and have pretty good perf. Flare design is synchronous but non-blocking still and was modelled after nginx which is in C and C has no native async either.

Once async lands in Mojo, It’ll be easy to support it in flare.

This is super cool, great work.

Re: async, it is a high priority for the mojo team. I don’t want to block anyone on waiting for it, but I also don’t want us to get attached to blocking sync apis. Let’s consider any I/O without async as something that is great for early development, but then will get revised when async comes on the scene.

-Chris