Documentation ¶
Overview ¶
Package grpchan provides an abstraction for a gRPC transport, called a Channel. The channel is more general than the concrete *grpc.ClientConn and *grpc.Server types provided by gRPC. It allows gRPC over alternate substrates and includes sub-packages that provide two such alternatives: in-process and HTTP 1.1.
The key type in this package is an alternate implementation of grpc.ServiceRegistrar interface that allows you to accumulate service registrations, for use with an implementation other than *grpc.Server.
Protoc Plugin ¶
This repo also includes a deprecated protoc plugin. This is no longer needed now that the standard protoc-gen-go-grpc plugin generates code that uses interfaces: grpc.ClientConnInterface and grpc.ServiceRegistrar. In older versions, the generated code only supported concrete types (*grpc.ClientConn and *grpc.Server) so this repo's protoc plugin would generate alternate code that used interfaces (and thus supported other concrete implementations).
Continued use of the plugin is only to continue supporting code that uses the functions generated by it.
To use the protoc plugin, you need to first build it and make sure its location is in your PATH.
go install github.com/fullstorydev/grpchan/cmd/protoc-gen-grpchan # If necessary, make sure its location is on your path like so: # export PATH=$PATH:$GOPATH/bin
When you invoke protoc, include a --grpchan_out parameter that indicates the same output directory as used for your --go_out parameter. Alongside the *.pb.go files generated, the grpchan plugin will also create *.pb.grpchan.go files.
In older versions of the Go plugin (when emitting gRPC code), a server registration function for each RPC service defined in the proto source files was generated that looked like so:
// A function with this signature is generated, for registering // server handlers with the given server. func Register<ServiceName>Server(s *grpc.Server, srv <ServiceName>Server) { s.RegisterService(&_<ServiceName>_serviceDesc, srv) }
The grpchan plugin produces a similarly named method that accepts the ServiceRegistry interface:
func RegisterHandler<ServiceName>(sr grpchan.ServiceRegistry, srv <ServiceName>Server) { s.RegisterService(&_<ServiceName>_serviceDesc, srv) }
A new transport can then be implemented by just implementing two interfaces: grpc.ClientConnInterface for the client side and grpchan.ServiceRegistry for the server side.
The alternate method also works just fine with *grpc.Server as it implements the ServiceRegistry interface.
NOTE: If your have code relying on New<ServiceName>ChannelClient methods that earlier versions of this package produced, they can still be generated by passing a "legacy_stubs" option to the plugin. Example:
protoc foo.proto --grpchan_out=legacy_stubs:./output/dir
Client-Side Channels ¶
The client-side implementation of a transport is done with just the two methods in grpc.ClientConnInterface: one for unary RPCs and the other for streaming RPCs.
Note that when a unary interceptor is invoked for an RPC on a channel that is *not* a *grpc.ClientConn, the parameter of that type will be nil.
Not all client call options will make sense for all transports. This repo chooses to ignore call options that do not apply (as opposed to failing the RPC or panicking). However, several call options are likely important to support: those for accessing header and trailer metadata. The peer, per-RPC credentials, and message size limits are other options that are reasonably straight-forward to apply to other transports. But the other options (dealing with on-the-wire encoding, compression, etc) may not be applicable.
Server-Side Service Registries ¶
The server-side implementation of a transport must be able to invoke method and stream handlers for a given service implementation. This is done by implementing the grpc.ServiceRegistrar interface. When a service is registered, a service description is provided that includes access to method and stream handlers. When the transport receives requests for RPC operations, it in turn invokes these handlers. For streaming operations, it must also supply a grpc.ServerStream implementation, for exchanging messages on the stream.
Note that the server stream's context will need a custom implementation of the grpc.ServerTransportStream in it, too. Sadly, this interface is just different enough from grpc.ServerStream that they cannot be implemented by the same type. This is particularly necessary for unary calls since this is how a unary handler indicates what headers and trailers to send back to the client.
Index ¶
- func InterceptChannel(ch grpc.ClientConnInterface, unaryInt grpc.UnaryClientInterceptor, ...) grpc.ClientConnInterfacedeprecated
- func InterceptClientConn(ch grpc.ClientConnInterface, unaryInt grpc.UnaryClientInterceptor, ...) grpc.ClientConnInterface
- func InterceptServer(svcDesc *grpc.ServiceDesc, unaryInt grpc.UnaryServerInterceptor, ...) *grpc.ServiceDesc
- type Channeldeprecated
- type HandlerMap
- type ServiceRegistrydeprecated
- type WrappedClientConn
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func InterceptChannel
deprecated
func InterceptChannel(ch grpc.ClientConnInterface, unaryInt grpc.UnaryClientInterceptor, streamInt grpc.StreamClientInterceptor) grpc.ClientConnInterface
InterceptChannel returns a new channel that intercepts RPCs with the given interceptors. If both given interceptors are nil, returns ch. Otherwise, the returned value will implement WrappedClientConn and its Unwrap() method will return ch.
Deprecated: Use InterceptClientConn instead.
func InterceptClientConn ¶ added in v1.1.0
func InterceptClientConn(ch grpc.ClientConnInterface, unaryInt grpc.UnaryClientInterceptor, streamInt grpc.StreamClientInterceptor) grpc.ClientConnInterface
InterceptClientConn returns a new channel that intercepts RPCs with the given interceptors. If both given interceptors are nil, returns ch. Otherwise, the returned value will implement WrappedClientConn and its Unwrap() method will return ch.
func InterceptServer ¶
func InterceptServer(svcDesc *grpc.ServiceDesc, unaryInt grpc.UnaryServerInterceptor, streamInt grpc.StreamServerInterceptor) *grpc.ServiceDesc
InterceptServer returns a new service description that will intercepts RPCs with the given interceptors. If both given interceptors are nil, returns svcDesc.
Types ¶
type Channel
deprecated
type Channel = grpc.ClientConnInterface
Channel is an abstraction of a GRPC transport. With corresponding generated code, it can provide an alternate transport to the standard HTTP/2-based one. For example, a Channel implementation could instead provide an HTTP 1.1-based transport, or an in-process transport.
Deprecated: Use grpc.ClientConnInterface instead.
type HandlerMap ¶
type HandlerMap map[string]service
HandlerMap is used to accumulate service handlers into a map. The handlers can be registered once in the map, and then re-used to configure multiple servers that should expose the same handlers. HandlerMap can also be used as the internal store of registered handlers for a server implementation.
func (HandlerMap) ForEach ¶
func (m HandlerMap) ForEach(fn func(desc *grpc.ServiceDesc, svr interface{}))
ForEach calls the given function for each registered handler. The function is provided the service description, and the handler. This can be used to contribute all registered handlers to a server and means that applications can easily expose the same services and handlers via multiple channels after registering the handlers once, with the map:
// Register all handlers once with the map: reg := channel.HandlerMap{} // (these registration functions are generated) foo.RegisterHandlerFooBar(newFooBarImpl()) fu.RegisterHandlerFuBaz(newFuBazImpl()) // Now we can re-use these handlers for multiple channels: // Normal gRPC svr := grpc.NewServer() reg.ForEach(svr.RegisterService) // In-process ipch := &inprocgrpc.Channel{} reg.ForEach(ipch.RegisterService) // And HTTP 1.1 httpgrpc.HandleServices(http.HandleFunc, "/rpc/", reg, nil, nil)
func (HandlerMap) GetServiceInfo ¶ added in v1.1.0
func (m HandlerMap) GetServiceInfo() map[string]grpc.ServiceInfo
GetServiceInfo returns a snapshot of information about the currently registered services in the map.
This mirrors the method of the same name on *grpc.Server.
func (HandlerMap) QueryService ¶
func (m HandlerMap) QueryService(name string) (*grpc.ServiceDesc, interface{})
QueryService returns the service descriptor and handler for the named service. If no handler has been registered for the named service, then nil, nil is returned.
func (HandlerMap) RegisterService ¶
func (m HandlerMap) RegisterService(desc *grpc.ServiceDesc, h interface{})
RegisterService registers the given handler to be used for the given service. Only a single handler can be registered for a given service. And services are identified by their fully-qualified name (e.g. "package.name.Service").
type ServiceRegistry
deprecated
type ServiceRegistry = grpc.ServiceRegistrar
ServiceRegistry accumulates service definitions. Servers typically have this interface for accumulating the services they expose.
Deprecated: Use grpc.ServiceRegistrar instead.
func WithInterceptor ¶
func WithInterceptor(reg ServiceRegistry, unaryInt grpc.UnaryServerInterceptor, streamInt grpc.StreamServerInterceptor) ServiceRegistry
WithInterceptor returns a view of the given ServiceRegistry that will automatically apply the given interceptors to all registered services.
type WrappedClientConn ¶ added in v1.1.0
type WrappedClientConn interface { grpc.ClientConnInterface Unwrap() grpc.ClientConnInterface }
WrappedClientConn is a channel that wraps another. It provides an Unwrap method for access the underlying wrapped implementation.
Directories ¶
Path | Synopsis |
---|---|
cmd
|
|
protoc-gen-grpchan
Command protoc-gen-grpchan is a protoc plugin that generates gRPC client stubs in Go that use github.com/fullstorydev/grpchan.Channel as their transport abstraction, instead of using *grpc.ClientConn.
|
Command protoc-gen-grpchan is a protoc plugin that generates gRPC client stubs in Go that use github.com/fullstorydev/grpchan.Channel as their transport abstraction, instead of using *grpc.ClientConn. |
Package grpchantesting helps with testing implementations of alternate gRPC transports.
|
Package grpchantesting helps with testing implementations of alternate gRPC transports. |
Package httpgrpc contains code for using HTTP 1.1 for GRPC calls.
|
Package httpgrpc contains code for using HTTP 1.1 for GRPC calls. |
Package inprocgrpc provides an in-process gRPC channel implementation.
|
Package inprocgrpc provides an in-process gRPC channel implementation. |