blob: 7642b5d62f48ad7906da44005f5585b1d5f7271e [file] [log] [blame]
GothamGo 2015
Sameer Ajmani
Tech Lead Manager, Go team, Google
* Video
This talk was presented at GothamGo in New York City, October 2015.
.link Watch the talk on YouTube
* RPC isn't just Remote Procedure Call
In Go, an RPC *starts*a*goroutine* running on the server and provides _message_passing_ between the client and server goroutines.
*Unary*RPC*: the client sends a _request_ to the server, then the server sends a _response_.
*Streaming*RPC:* the client and server may each send one or more messages.
An RPC ends when:
- both sides are done sending messages
- either side disconnects
- the RPC is canceled or times out
This talk will show how we connect RPCs and streams with goroutines and channels.
* Unary RPC: one request, one response
Example: a mobile Maps app requests a route from point A to point B.
On the client side, an RPC blocks until it's done or canceled.
A client uses multiple goroutines to run many RPCs simultaneously.
Each RPC is an exchange between a client goroutine and a server goroutine.
* Streaming RPC provides bidirectional message-passing
A client starts a stream with a server.
Messages sent on a stream are delivered FIFO.
Many streams can run simultaneously between the same client and server.
The transport provides buffering and flow control.
- bidirectional stream: chat session
- server client stream: stock ticker
- client server stream: sensor aggregation
* gRPC is a new RPC system from Google
Provides RPC and streaming RPC
Ten languages: *C*, *Java*, *Go*, C++, Node.js, Python, Ruby, Objective-C, PHP, and C#
IDL: *Proto3*
Transport: *HTTP2*
[[][]] for deadlines, cancellation, and request-scoped values
[[][]] for real-time request traces and connection logging
* gRPC users
150+ imports of [[][]] on [[][]]
- [[][Apcera/Kurma]]: container OS
- [[][Bazil]]: distributed file system
- [[][CoreOS/Etcd]]: distributed consistent key-value store
- [[][Google Cloud Bigtable]]: sparse table storage
- [[][Monetas/Bitmessage]]: transaction platform
- [[][Pachyderm]]: containerized data analytics
- [[][YouTube/Vitess]]: storage platform for scaling MySQL
* Demos and Code: Google search
* Protocol definition
.code gotham-grpc/search-only/search-only.proto
* Generated code
.code gotham-grpc/search/ /protoc/
.code gotham-grpc/search-only/search-only.pb.go /type GoogleClient/,/^}/
.code gotham-grpc/search-only/search-only.pb.go /type GoogleServer/,/^}/
.code gotham-grpc/search-only/search-only.pb.go /type Request/,/^}/
.code gotham-grpc/search-only/search-only.pb.go /type Result/,/^}/
* System diagram
.image gotham-grpc/system.svg _ 1000
* Frontend runs Search on both backends and returns first result
.image gotham-grpc/search.svg _ 1000
* Demo client --mode=search
- Frontend request traces
- Backend request traces
- Connection event logs
* Client code
.image gotham-grpc/client.svg _ 1000
* Client code (main)
import pb ""
.code gotham-grpc/client/client.go /func main/,/^}/
* Client code (search)
.code gotham-grpc/client/client.go /func search/,/^}/
RPCs block but can be canceled using a Context.
gRPC propagates cancellation from client to server.
* Backend code
.image gotham-grpc/backend.svg _ 1000
* Backend code (main)
.code gotham-grpc/backend/backend.go /net.Listen/,/g.Serve/
`new(server)` must implement the `GoogleServer` interface:
.code gotham-grpc/search/search.pb.go /type GoogleServer/,/^}/
Each call to `Search` or `Watch` runs in its own goroutine.
* Backend code (search)
`ctx.Done` is closed when the RPC is canceled, times out, or returns:
.code gotham-grpc/backend/backend.go /[)] Search/,/^}/
If tracing is enabled, log the sleep duration:
.code gotham-grpc/backend/backend.go /func logSleep/,/^}/
* Frontend code
.image gotham-grpc/frontend.svg _ 1000
* Frontend code (search)
`Search` returns as soon as it gets the first result.
gRPC cancels the remaining `backend.Search` RPCs by via `ctx`:
.code gotham-grpc/frontend/frontend.go /[)] Search/,/^}/
.code gotham-grpc/frontend/frontend.go /type result/,/^}/
* Streaming RPC
* Add Watch to the Google service
.code gotham-grpc/search/search.proto
* Generated code
.code gotham-grpc/search/search.pb.go /type GoogleClient/,/^}/
.code gotham-grpc/search/search.pb.go /type GoogleServer/,/^}/
.code gotham-grpc/search/search.pb.go /type Google_WatchClient/,/^}/
.code gotham-grpc/search/search.pb.go /type Google_WatchServer/,/^}/
* Frontend runs Watch on both backends and merges results
.image gotham-grpc/watch.svg _ 1000
* Demo client --mode=watch
- Active stream traces
- Cancellation
* Client code
.image gotham-grpc/client.svg _ 1000
* Client code (watch)
.code gotham-grpc/client/client.go /func watch/,/^}/
* Backend code
.image gotham-grpc/backend.svg _ 1000
* Backend code (watch)
.code gotham-grpc/backend/backend.go /[)] Watch/,/^}/
* Frontend code
.image gotham-grpc/frontend.svg _ 1000
* Frontend code (watch)
.code gotham-grpc/frontend/frontend.go /[)] Watch/,/return nil/
* Frontend code (watchBackend)
`Watch` returns on first error; this closes `ctx.Done` and signals `watchBackend` to exit.
.code gotham-grpc/frontend/frontend.go /func watch/,/^}/
* gRPC extends the Go programming model over the network
Go gRPC works smoothly with goroutines, channels, and cancellation.
It is an excellent fit for building parallel, distributed, and streaming systems.
.image gotham-grpc/watch.svg _ 1000
* References
- [[][]] - gRPC reference and tutorials
- [[][]] - Protocol buffers
- [[][]] - HTTP2
- [[][]] - Request traces and event logs
- [[][]] - Cancellation and request-scoped data
- [[][]] - Streaming data pipelines
*Thanks*to* Qi Zhao, David Symonds, Brad Fitzpatrick, and the rest.
Sameer Ajmani
Tech Lead Manager, Go team, Google