thrift

package
v1.75.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2024 License: MIT Imports: 23 Imported by: 5

Documentation

Overview

Package thrift implements Thrift encoding support for YARPC.

To use this package, you must install ThriftRW 1.0 or newer.

go get go.uber.org/thriftrw

You must also install the ThriftRW plugin for YARPC.

go get go.uber.org/yarpc/encoding/thrift/thriftrw-plugin-yarpc

To generate YARPC compatible code from a Thrift file, use the command,

thriftrw --plugin yarpc myservice.thrift

In addition to generating code for types specified in your Thrift file, this will generate the following packages for each service in the file: a client package, a server package, a test package, and an UberFx module.

myservice
   |- myserviceclient
   |- myserviceserver
   |- myservicefx
   |- myservicetest

The client package allows sending requests through a YARPC dispatcher.

client := myserviceclient.New(dispatcher.ClientConfig("myservice"))

The server package facilitates registration of service implementations with a YARPC dispatcher.

handler := myHandler{}
dispatcher.Register(myserviceserver.New(handler))

The test package provides a gomock-compatible mock client for the service.

mockCtrl := gomock.NewController(t)
client := myservicetest.NewMockClient(mockCtrl)
client.EXPECT().Hello(request).Return(response, nil)

The Fx package provides an UberFx-compatible constructor for service clients. This may be used with Provide to make service clients available in the container.

fx.Provide(myservicefx.Client("myservice"))

The Fx package also provides an UberFx-compatible constructor for registering service procedures. This expects an instance of the service interface to be available in the container and provides the list of procedures resulting from that to the "yarpcfx" value group.

fx.Provide(
	myservicefx.Server(),
	NewMyServiceHandler,  // func(...) myserviceserver.Interface
)

Automatically Building Clients

All clients generated by the YARPC ThriftRW plugin are compatible with YARPC's yarpc.InjectClients function.

var handler struct{ Client keyvalueclient.Interface `service:"keyvalue"` }
yarpc.Injectclients(dispatcher, &handler)

These clients may further be customized by providing a "thrift" tag. The following options may be provided on the tag using a comma-separated list.

enveloped:   Requests and responses will be wrapped inside a standard
             Apache Thrift envelope. This flag is needed to call existing
             Apache Thrift services with clients generated by YARPC.
             Equivalent to passing thrift.Enveloped.
multiplexed: Requests are being sent to an Apache Thrift server which has
             multiplexing enabled. Equivalent to passing
             thrift.Multiplexed. This option has no effect if enveloped
             was not set.

For example,

type handler struct {
	Client keyvalueclient.Interface `service:"keyvalue" thrift:"multiplexed,enveloped"`
}

var h handler
yarpc.Injectclients(dispatcher, &h)

Calling Existing Apache Thrift Services

You can call existing Apache Thrift services with YARPC by passing in the thrift.Enveloped option when constructing the corresponding clients.

client := myserviceclient.New(dispatcher.ClientConfig("myservice"), thrift.Enveloped)

With yarpc.InjectClients, you can pass the tag `thrift:"enveloped"` to enable this option on automatically instantiated clients.

type handler struct {
	Client myserviceclient.Interface `service:"myservice" thrift:"enveloped"`
}

var h handler
yarpc.InjectClients(dispatcher, &h)

Automatically Sanitizing TChannel Contexts

Contexts created with `tchannel.ContextWithHeaders` are incompatible with YARPC clients generated from Thrift. Using such a context will cause a YARPC client to error on any call. Using the `sanitize-tchannel` flag will generate a YARPC client such that all TChannel headers from any context supplied are removed before making a YARPC call. The option can be used like so:

thriftrw --plugin "yarpc --sanitize-tchannel" myservice.thrift

Index

Constants

View Source
const Encoding transport.Encoding = "thrift"

Encoding is the name of this encoding.

Variables

This section is empty.

Functions

func BuildProcedures added in v1.0.0

func BuildProcedures(s Service, opts ...RegisterOption) []transport.Procedure

BuildProcedures builds a list of Procedures from a Thrift service specification.

func Register deprecated

func Register(r transport.RouteTable, rs []transport.Procedure)

Register calls the RouteTable's Register method.

This function exists for backwards compatibility only. It will be removed in a future version.

Deprecated: Use the RouteTable's Register method directly.

Types

type Client

type Client interface {
	// Call the given Thrift method.
	Call(ctx context.Context, reqBody envelope.Enveloper, opts ...yarpc.CallOption) (wire.Value, error)
	CallOneway(ctx context.Context, reqBody envelope.Enveloper, opts ...yarpc.CallOption) (transport.Ack, error)
}

Client is a generic Thrift client. It speaks in raw Thrift payloads.

Users should use the client generated by the code generator rather than using this directly.

func New

func New(c Config, opts ...ClientOption) Client

New creates a new Thrift client.

type ClientOption

type ClientOption interface {
	// contains filtered or unexported methods
}

ClientOption customizes the behavior of a Thrift client.

var Multiplexed ClientOption = multiplexedOption{}

Multiplexed is an option that specifies that requests from a client should use Thrift multiplexing. This option should be used if the remote server is using Thrift's TMultiplexedProtocol. It includes the name of the service in the envelope name for all outbound requests.

Specify this option when constructing the Thrift client.

client := myserviceclient.New(clientConfig, thrift.Multiplexed)

This option has no effect if enveloping is disabled.

func ClientBuilderOptions added in v1.8.0

func ClientBuilderOptions(_ transport.ClientConfig, f reflect.StructField) []ClientOption

ClientBuilderOptions returns ClientOptions that InjectClients should use for a specific Thrift client given information about the field into which the client is being injected. This API will usually not be used directly by users but by the generated code.

type Config

type Config struct {
	// Name of the Thrift service. This is the name used in the Thrift file
	// with the 'service' keyword.
	Service string

	// ClientConfig through which requests will be sent. Required.
	ClientConfig transport.ClientConfig
}

Config contains the configuration for the Client.

type HandlerSpec added in v1.0.0

type HandlerSpec struct {
	Type   transport.Type
	Unary  UnaryHandler
	Oneway OnewayHandler
	NoWire NoWireHandler
}

HandlerSpec represents the handler behind a Thrift service method.

type Method added in v1.0.0

type Method struct {
	// Name of the method itself.
	Name string

	// The handler to call.
	HandlerSpec HandlerSpec

	// Snippet of Go code representing the function definition of the handler.
	// This is useful for introspection.
	Signature string

	// ThriftModule, if non-nil, refers to the Thrift module from where this
	// method is coming from.
	ThriftModule *thriftreflect.ThriftModule
}

Method represents a Thrift service method.

type NoWireCall added in v1.57.0

type NoWireCall struct {
	Reader        io.Reader
	RequestReader stream.RequestReader
	EnvelopeType  wire.EnvelopeType
}

NoWireCall contains all of the required objects needed for an underlying Handle needs to unpack any given request.

type NoWireClient added in v1.57.0

type NoWireClient interface {
	// Call the given Thrift method.
	Call(ctx context.Context, reqBody stream.Enveloper, resBody stream.BodyReader, opts ...yarpc.CallOption) error
	CallOneway(ctx context.Context, reqBody stream.Enveloper, opts ...yarpc.CallOption) (transport.Ack, error)

	// Enabled returns whether or not this client is enabled through a
	// ClientOption. This ClientOption is toggled through the 'NoWire(bool)'
	// option.
	Enabled() bool
}

NoWireClient is a generic Thrift client for encoding/decoding using ThriftRW's "streaming" mechanisms. The body of the provided request ('reqBody') will be written out through its method 'Encode', while the body of the response ('resBody') is read out through its method 'Decode'. It speaks in raw Thrift payloads.

Users should use the client generated by the code generator rather than using this directly.

func NewNoWire added in v1.57.0

func NewNoWire(c Config, opts ...ClientOption) NoWireClient

NewNoWire creates a new Thrift client that leverages ThriftRW's "streaming" implementation.

type NoWireHandler added in v1.57.0

type NoWireHandler interface {
	HandleNoWire(context.Context, *NoWireCall) (NoWireResponse, error)
}

NoWireHandler is implemented by the generated code for each method that the server needs to implement. It is responsible for unpacking the request, executing it, and returning a NoWireResponse that contains information about how to construct a response as well as any relevant metadata while executing the request.

type NoWireResponse added in v1.57.0

type NoWireResponse struct {
	// Body contains the response body. It knows how to encode itself into
	// the "nowire" representation.
	Body stream.Enveloper

	// ResponseWriter encodes the body into an output stream.
	ResponseWriter stream.ResponseWriter

	// IsApplicationError reports whether the response indicates an
	// appliation-level error. If true, a Thrift exception was thrown by
	// the handler.
	IsApplicationError bool

	ApplicationErrorDetails string
	ApplicationErrorName    string
	ApplicationErrorCode    *yarpcerrors.Code
}

NoWireResponse is the response from a generated Thrift handler that can process requests that use the "nowire" implementation.

type OnewayHandler added in v0.4.0

type OnewayHandler func(context.Context, wire.Value) error

OnewayHandler is a convenience type alias for functions that act as OnewayHandlers.

type Option

type Option interface {
	ClientOption
	RegisterOption
}

Option unifies options that apply to both, Thrift clients and handlers.

var Enveloped Option = envelopedOption{}

Enveloped is an option that specifies that Thrift requests and responses should be enveloped. It defaults to false.

It may be specified on the client side when the client is constructed.

client := myserviceclient.New(clientConfig, thrift.Enveloped)

It may be specified on the server side when the handler is registered.

dispatcher.Register(myserviceserver.New(handler, thrift.Enveloped))

Note that you will need to enable enveloping to communicate with Apache Thrift HTTP servers.

func Named added in v1.34.0

func Named(n string) Option

Named is an option that specifies the name of a thrift.Client. This option should be used if a thrift service extends another thrift service. Note that the first Named Option will trump all other Named options. This ensures that the inherited procedures are appropriately labelled with the correct inheriting service's name.

Specify this option when constructing the Thrift client.

client := myserviceclient.New(clientConfig, thrift.Named("foo"))

It may be specified on the server side when the handler is registered.

dispatcher.Register(myserviceserver.New(handler, thrift.Named("foo")))

If not specified, the client or server's inherited procedures will be labelled with the service name from which they are inherited.

func NoWire added in v1.57.0

func NoWire(enable bool) Option

NoWire is an option that specifies to *not* use the thriftrw.Wire intermediary format. Note that if this is enabled, and a 'protocol.Protocol' is provided (e.g., via thrift.Protocol) that provided protocol must be able to satisfy the 'stream.RequestReader' interface. Will become the default option.

func Protocol added in v0.4.0

func Protocol(p protocol.Protocol) Option

Protocol is an option that specifies which Thrift Protocol servers and clients should use. It may be specified on the client side when the client is constructed,

client := myserviceclient.New(clientConfig, thrift.Protocol(protocol.Binary))

It may be specified on the server side when the handler is registered.

dispatcher.Register(myserviceserver.New(handler, thrift.Protocol(protocol.Binary)))

It defaults to the Binary protocol.

type RegisterOption

type RegisterOption interface {
	// contains filtered or unexported methods
}

RegisterOption customizes the behavior of a Thrift handler during registration.

type Response

type Response struct {
	Body envelope.Enveloper

	IsApplicationError bool

	ApplicationErrorDetails string
	ApplicationErrorName    string
	ApplicationErrorCode    *yarpcerrors.Code
}

Response contains the raw response from a generated Thrift handler.

type Service

type Service struct {
	// Name of the Thrift service. This is the name specified for the service
	// in the IDL.
	Name    string
	Methods []Method
}

Service is a generic Thrift service implementation.

type UnaryHandler added in v0.4.0

type UnaryHandler func(context.Context, wire.Value) (Response, error)

UnaryHandler is a convenience type alias for functions that act as Handlers.

Directories

Path Synopsis
observabilitytest/test/testservicefx
Package testservicefx provides better integration for Fx for services implementing or calling TestService.
Package testservicefx provides better integration for Fx for services implementing or calling TestService.
thriftrw-plugin-yarpc implements a plugin for ThriftRW that generates code compatible with YARPC.
thriftrw-plugin-yarpc implements a plugin for ThriftRW that generates code compatible with YARPC.
internal/tests/atomic/readonlystorefx
Package readonlystorefx provides better integration for Fx for services implementing or calling ReadOnlyStore.
Package readonlystorefx provides better integration for Fx for services implementing or calling ReadOnlyStore.
internal/tests/atomic/storefx
Package storefx provides better integration for Fx for services implementing or calling Store.
Package storefx provides better integration for Fx for services implementing or calling Store.
internal/tests/common/baseservicefx
Package baseservicefx provides better integration for Fx for services implementing or calling BaseService.
Package baseservicefx provides better integration for Fx for services implementing or calling BaseService.
internal/tests/common/emptyservicefx
Package emptyservicefx provides better integration for Fx for services implementing or calling EmptyService.
Package emptyservicefx provides better integration for Fx for services implementing or calling EmptyService.
internal/tests/common/extendemptyfx
Package extendemptyfx provides better integration for Fx for services implementing or calling ExtendEmpty.
Package extendemptyfx provides better integration for Fx for services implementing or calling ExtendEmpty.
internal/tests/common/extendonlyfx
Package extendonlyfx provides better integration for Fx for services implementing or calling ExtendOnly.
Package extendonlyfx provides better integration for Fx for services implementing or calling ExtendOnly.
internal/tests/extends/barfx
Package barfx provides better integration for Fx for services implementing or calling Bar.
Package barfx provides better integration for Fx for services implementing or calling Bar.
internal/tests/extends/foofx
Package foofx provides better integration for Fx for services implementing or calling Foo.
Package foofx provides better integration for Fx for services implementing or calling Foo.
internal/tests/extends/namefx
Package namefx provides better integration for Fx for services implementing or calling Name.
Package namefx provides better integration for Fx for services implementing or calling Name.
internal/tests/weather/weatherfx
Package weatherfx provides better integration for Fx for services implementing or calling Weather.
Package weatherfx provides better integration for Fx for services implementing or calling Weather.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL