Documentation
¶
Overview ¶
Package thriftbp provides Baseplate specific thrift related helpers.
Clients ¶
On the client side, this package provides a middleware framework for thrift.TClient to allow you to automatically run code before and after making a Thrift call. It also includes middleware implementations to wrap each call in a Thrift client span as well as a function that most services can use as the "golden path" for setting up a Thrift client pool.
Servers ¶
On the server side, this package provides middleware implementations for EdgeRequestContext handling and tracing propagation according to Baseplate spec.
Example (ClientPool) ¶
This example demonstrates a typical use case of thriftbp pool in microservice code with custom middleware.
package main
import (
"context"
"time"
"github.com/apache/thrift/lib/go/thrift"
"github.com/reddit/baseplate.go/log"
"github.com/reddit/baseplate.go/thriftbp"
)
// In real code these should be coming from either config file or flags instead.
const (
remoteAddr = "host:port"
socketTimeout = time.Millisecond * 10
initialConnections = 50
maxConnections = 100
clientTTL = time.Minute * 5
poolGaugeInterval = time.Second * 10
)
// BEGIN THRIFT GENERATED CODE SECTION
//
// In real code this section should be from thrift generated code instead,
// but for this example we just define some placeholders here.
type MyEndpointRequest struct{}
type MyEndpointResponse struct{}
type MyService interface {
MyEndpoint(ctx context.Context, req *MyEndpointRequest) (*MyEndpointResponse, error)
}
func NewMyServiceClient(_ thrift.TClient) MyService {
// In real code this certainly won't return nil.
return nil
}
// END THRIFT GENERATED CODE SECTION
type Client interface {
thriftbp.Client
MyService
}
type clientImpl struct {
thriftbp.Client
MyService
}
func newClient(pool thriftbp.ClientPool) (Client, error) {
client, err := pool.GetClient()
if err != nil {
return nil, err
}
return &clientImpl{
MyService: NewMyServiceClient(client),
Client: client,
}, nil
}
func callEndpoint(ctx context.Context, pool thriftbp.ClientPool) (*MyEndpointResponse, error) {
client, err := newClient(pool)
if err != nil {
return nil, err
}
defer pool.ReleaseClient(client)
return client.MyEndpoint(ctx, &MyEndpointRequest{})
}
func LoggingMiddleware(next thrift.TClient) thrift.TClient {
return thrift.WrappedTClient{
Wrapped: func(ctx context.Context, method string, args, result thrift.TStruct) error {
log.Infof("pre: %s", method)
log.Infof("args: %#v", args)
defer func() {
log.Infof("after: %s", method)
}()
return next.Call(ctx, method, args, result)
},
}
}
// This example demonstrates a typical use case of thriftbp pool in
// microservice code with custom middleware.
func main() {
pool, err := thriftbp.NewBaseplateClientPool(
thriftbp.ClientPoolConfig{
ServiceSlug: "my-service",
Addr: remoteAddr,
InitialConnections: initialConnections,
MaxConnections: maxConnections,
SocketTimeout: socketTimeout,
ReportPoolStats: true,
PoolGaugeInterval: poolGaugeInterval,
},
clientTTL,
LoggingMiddleware,
)
if err != nil {
panic(err)
}
if _, err = callEndpoint(context.Background(), pool); err != nil {
panic(err)
}
}
Index ¶
- Constants
- Variables
- func AttachEdgeRequestContext(ctx context.Context, ec *edgecontext.EdgeRequestContext) context.Context
- func BaseplateDefaultClientMiddlewares() []thrift.ClientMiddleware
- func BaseplateDefaultProcessorMiddlewares(ecImpl *edgecontext.Impl) []thrift.ProcessorMiddleware
- func CopyTStruct(from, to thrift.TStruct) error
- func CreateThriftContextFromSpan(ctx context.Context, span *tracing.Span) context.Context
- func ExtractDeadlineBudget(name string, next thrift.TProcessorFunction) thrift.TProcessorFunction
- func ForwardEdgeRequestContext(next thrift.TClient) thrift.TClient
- func GetMockTProcessorName(ctx context.Context) (string, bool)
- func InitializeEdgeContext(ctx context.Context, impl *edgecontext.Impl) context.Context
- func InjectEdgeContext(impl *edgecontext.Impl) thrift.ProcessorMiddleware
- func InjectServerSpan(name string, next thrift.TProcessorFunction) thrift.TProcessorFunction
- func Merge(processors ...thrift.TProcessor) thrift.TProcessor
- func MonitorClient(next thrift.TClient) thrift.TClient
- func NewBaseplateServer(bp baseplate.Baseplate, processor thrift.TProcessor, ...) (baseplate.Server, error)
- func NewServer(cfg ServerConfig, processor thrift.TProcessor, ...) (*thrift.TSimpleServer, error)
- func SetDeadlineBudget(next thrift.TClient) thrift.TClient
- func SetMockTProcessorName(ctx context.Context, name string) context.Context
- func StandardTClientFactory(trans thrift.TTransport, protoFactory thrift.TProtocolFactory) thrift.TClient
- func StartSpanFromThriftContext(ctx context.Context, name string) (context.Context, *tracing.Span)
- type AddressGenerator
- type Client
- type ClientFactory
- type ClientPool
- type ClientPoolConfig
- type MockCall
- type MockClient
- type MockClientPool
- type MockTProcessor
- type RecordedCall
- type RecordedClient
- type ServerConfig
- type TClientFactory
- type TTLClient
Examples ¶
Constants ¶
const ( // The Trace ID, a 64-bit integer encoded in decimal. HeaderTracingTrace = "Trace" // The Span ID, a 64-bit integer encoded in decimal. HeaderTracingSpan = "Span" // The Parent Span ID, a 64-bit integer encoded in decimal. HeaderTracingParent = "Parent" // The Sampled flag, an ASCII "1" (HeaderTracingSampledTrue) if true, // otherwise false. // If not present, defaults to false. HeaderTracingSampled = "Sampled" // Trace flags, a 64-bit integer encoded in decimal. // If not present, defaults to null. HeaderTracingFlags = "Flags" )
Tracing related headers, as defined in https://pages.github.snooguts.net/reddit/baseplate.spec/component-apis/thrift#tracing
const DefaultPoolGaugeInterval = time.Second * 10
DefaultPoolGaugeInterval is the fallback value to be used when ClientPoolConfig.PoolGaugeInterval <= 0.
const (
// Number of milliseconds, 64-bit integer encoded in decimal.
HeaderDeadlineBudget = "Deadline-Budget"
)
Deadline propagation related headers.
const (
HeaderEdgeRequest = "Edge-Request"
)
Edge request context propagation related headers, as defined in https://pages.github.snooguts.net/reddit/baseplate.spec/component-apis/thrift#edge-request-context-propagation
const HeaderTracingSampledTrue = "1"
HeaderTracingSampledTrue is the header value to indicate that this trace should be sampled.
Variables ¶
var HeadersToForward = []string{ HeaderEdgeRequest, HeaderTracingTrace, HeaderTracingSpan, HeaderTracingParent, HeaderTracingSampled, HeaderTracingFlags, }
HeadersToForward are the headers that should always be forwarded to upstream thrift servers, to be used in thrift.TSimpleServer.SetForwardHeaders.
Functions ¶
func AttachEdgeRequestContext ¶
func AttachEdgeRequestContext(ctx context.Context, ec *edgecontext.EdgeRequestContext) context.Context
AttachEdgeRequestContext returns a context that has the header of the given EdgeRequestContext set to forward using the "Edge-Request" header on any Thrift calls made with that context object.
func BaseplateDefaultClientMiddlewares ¶
func BaseplateDefaultClientMiddlewares() []thrift.ClientMiddleware
BaseplateDefaultClientMiddlewares returns the default client middlewares that should be used by a baseplate service.
Currently they are (in order):
1. MonitorClient
2. ForwardEdgeRequestContext
3. SetDeadlineBudget
func BaseplateDefaultProcessorMiddlewares ¶
func BaseplateDefaultProcessorMiddlewares(ecImpl *edgecontext.Impl) []thrift.ProcessorMiddleware
BaseplateDefaultProcessorMiddlewares returns the default processor
middlewares that should be used by a baseplate Thrift service.
Currently they are (in order):
1. ExtractDeadlineBudget
2. InjectServerSpan
3. InjectEdgeContext
func CopyTStruct ¶
CopyTStruct is a helper function that can be used to implement MockCall.
In thrift.TClient and MockCall interfaces, the result is passed in as an arg to the function, so you can't directly assign a result to it. Instead, you'll need to use this helper function to copy a constructed result to the arg.
Example:
myMockClient.AddMockCall(
"myEndpoint",
func(ctx context.Context, args, result thrift.TStruct) error {
return thriftbp.CopyTStruct(
&myservice.MyServiceMyEndpointResult{
Success: &myservice.MyEndpointResponse{
// Set the response fields.
},
},
result,
)
},
)
func CreateThriftContextFromSpan ¶
CreateThriftContextFromSpan injects span info into a context object that can be used in thrift client code. If you are using a client pool created using thriftbp.NewBaseplateClientPool, all of your thrift calls will already be call this automatically, so there is no need to use it directly.
Caller should first create a client child-span for the thrift call as usual, then use that span and the parent context object with this call, then use the returned context object in the thrift call. Something like:
span, clientCtx := opentracing.StartSpanFromContext(
ctx,
"myCall",
tracing.SpanTypeOption{Type: tracing.SpanTypeClient},
)
clientCtx = thriftbp.CreateThriftContextFromSpan(clientCtx, tracing.AsSpan(span))
result, err := client.MyCall(clientCtx, arg1, arg2)
span.FinishWithOptions(tracing.FinishOptions{
Ctx: clientCtx,
Err: err,
}.Convert())
func ExtractDeadlineBudget ¶
func ExtractDeadlineBudget(name string, next thrift.TProcessorFunction) thrift.TProcessorFunction
ExtractDeadlineBudget is the server middleware implementing Phase 1 of Baseplate deadline propagation.
It only sets the timeout if the passed in deadline is at least 1ms.
func ForwardEdgeRequestContext ¶
ForwardEdgeRequestContext forwards the EdgeRequestContext set on the context object to the Thrift service being called if one is set.
If you are using a thrift ClientPool created by NewBaseplateClientPool, this will be included automatically and should not be passed in as a ClientMiddleware to NewBaseplateClientPool.
func GetMockTProcessorName ¶
GetMockTProcessorName gets the "name" of the TProcessorFunction to call on a MockTProcessor when calling Process.
func InitializeEdgeContext ¶
InitializeEdgeContext sets an edge request context created from the Thrift headers set on the context onto the context and configures Thrift to forward the edge requent context header on any Thrift calls made by the server.
func InjectEdgeContext ¶
func InjectEdgeContext(impl *edgecontext.Impl) thrift.ProcessorMiddleware
InjectEdgeContext returns a ProcessorMiddleware that injects an edge request context created from the Thrift headers set on the context into the `next` thrift.TProcessorFunction.
Note, this depends on the edge context headers already being set on the context object. These should be automatically injected by your thrift.TSimpleServer.
func InjectServerSpan ¶
func InjectServerSpan(name string, next thrift.TProcessorFunction) thrift.TProcessorFunction
InjectServerSpan implements thrift.ProcessorMiddleware and injects a server span into the `next` context.
Starts the server span before calling the `next` TProcessorFunction and stops the span after it finishes. If the function returns an error, that will be passed to span.Stop.
Note, the span will be created according to tracing related headers already being set on the context object. These should be automatically injected by your thrift.TSimpleServer.
func Merge ¶
func Merge(processors ...thrift.TProcessor) thrift.TProcessor
Merge merges together multiple processors into the first one.
It's useful when the server needs to support more than one separated thrift file.
It's kind of like thrift's TMultiplexedProcessor. The key difference is that TMultiplexedProcessor requires the client to also use TMultiplexedProtocol, while here the client doesn't need any special handling.
func MonitorClient ¶
MonitorClient is a ClientMiddleware that wraps the inner thrift.TClient.Call in a thrift client span.
If you are using a thrift ClientPool created by NewBaseplateClientPool, this will be included automatically and should not be passed in as a ClientMiddleware to NewBaseplateClientPool.
Example ¶
This example illustrates what thriftbp.MonitorClient does specifically and the details of how thriftbp.WrapClient works, a typical service will not write code like this and will instead be creating a ClientPool using thriftbp.NewBaseplateClientPool.
package main
import (
"context"
"github.com/apache/thrift/lib/go/thrift"
opentracing "github.com/opentracing/opentracing-go"
"github.com/reddit/baseplate.go/internal/gen-go/reddit/baseplate"
"github.com/reddit/baseplate.go/log"
"github.com/reddit/baseplate.go/thriftbp"
"github.com/reddit/baseplate.go/tracing"
)
func main() {
// variables should be properly initialized in production code
var (
transport thrift.TTransport
factory thrift.TProtocolFactory
)
// Create an actual service client
client := baseplate.NewBaseplateServiceClient(
// Use MonitoredClient to wrap a standard thrift client
thriftbp.NewWrappedTClientFactory(
thriftbp.StandardTClientFactory,
thriftbp.MonitorClient,
)(transport, factory),
)
// Create a context with a server span
_, ctx := opentracing.StartSpanFromContext(
context.Background(),
"test",
tracing.SpanTypeOption{Type: tracing.SpanTypeServer},
)
// Calls should be automatically wrapped using client spans
healthy, err := client.IsHealthy(ctx)
log.Debug("%v, %s", healthy, err)
}
func NewBaseplateServer ¶
func NewBaseplateServer( bp baseplate.Baseplate, processor thrift.TProcessor, middlewares ...thrift.ProcessorMiddleware, ) (baseplate.Server, error)
NewBaseplateServer returns a new Thrift implementation of a Baseplate server with the given TProcessor.
The TProcessor underlying the server will be wrapped in the default Baseplate Middleware and any additional middleware passed in.
Example ¶
This example demonstrates what a typical main function should look like for a Baseplate thrift service.
package main
import (
"context"
baseplate "github.com/reddit/baseplate.go"
bpgen "github.com/reddit/baseplate.go/internal/gen-go/reddit/baseplate"
"github.com/reddit/baseplate.go/log"
"github.com/reddit/baseplate.go/thriftbp"
)
func main() {
ctx, bp, err := baseplate.New(context.Background(), "example.yaml", nil)
if err != nil {
panic(err)
}
defer bp.Close()
// In real prod code, you should define your thrift endpoints and create this
// handler instead.
var handler bpgen.BaseplateService
processor := bpgen.NewBaseplateServiceProcessor(handler)
server, err := thriftbp.NewBaseplateServer(bp, processor)
if err != nil {
log.Fatal(err)
}
log.Info(baseplate.Serve(ctx, server))
}
func NewServer ¶
func NewServer( cfg ServerConfig, processor thrift.TProcessor, middlewares ...thrift.ProcessorMiddleware, ) (*thrift.TSimpleServer, error)
NewServer returns a thrift.TSimpleServer using the THeader transport and protocol to serve the given TProcessor which is wrapped with the given ProcessorMiddlewares.
func SetDeadlineBudget ¶
SetDeadlineBudget is the client middleware implementing Phase 1 of Baseplate deadline propogation.
func SetMockTProcessorName ¶
SetMockTProcessorName sets the "name" of the TProcessorFunction to call on a MockTProcessor when calling Process.
In a normal TProcessor, the request name is read from the request itself which happens in TProcessor.Process, so it is not passed into the call to Process itself, to get around this, MockTProcessor calls GetMockTProcessorName to get the name to use from the context object.
func StandardTClientFactory ¶
func StandardTClientFactory(trans thrift.TTransport, protoFactory thrift.TProtocolFactory) thrift.TClient
StandardTClientFactory returns a standard thrift.TClient using the given thrift.TTransport and thrift.TProtocolFactory
Services should generally not have to use StandardTClientFactory directly, instead you should use NewBaseplateClientPool which uses the default TClientFactory for a typical Baseplate Thrift Client.
func StartSpanFromThriftContext ¶
StartSpanFromThriftContext creates a server span from thrift context object.
This span would usually be used as the span of the whole thrift endpoint handler, and the parent of the child-spans.
Caller should pass in the context object they got from thrift library, which would have all the required headers already injected.
Please note that "Sampled" header is default to false according to baseplate spec, so if the context object doesn't have headers injected correctly, this span (and all its child-spans) will never be sampled, unless debug flag was set explicitly later.
If any of the tracing related thrift header is present but malformed, it will be ignored. The error will also be logged if InitGlobalTracer was last called with a non-nil logger. Absent tracing related headers are always silently ignored.
Types ¶
type AddressGenerator ¶
AddressGenerator defines a function that returns the address of a thrift service.
Services should generally not have to use AddressGenerators directly, instead you should use NewBaseplateClientPool which uses the default AddressGenerator for a typical Baseplate Thrift Client.
func SingleAddressGenerator ¶
func SingleAddressGenerator(addr string) AddressGenerator
SingleAddressGenerator returns an AddressGenerator that always returns addr.
Services should generally not have to use SingleAddressGenerator directly, instead you should use NewBaseplateClientPool which uses the default AddressGenerator for a typical Baseplate Thrift Client.
type Client ¶
type Client interface {
clientpool.Client
thrift.TClient
}
Client is a client object that implements both the clientpool.Client and thrift.TCLient interfaces.
This allows it to be managed by a clientpool.Pool and be passed to a thrift client as the base thrift.TClient.
type ClientFactory ¶
type ClientFactory func(TClientFactory, thrift.TTransport, thrift.TProtocolFactory) Client
ClientFactory defines a function that builds a Client object using a the thrift primitives required to create a thrift.TClient.
Services should generally not have to use ClientFactories directly, instead you should use NewBaseplateClientPool which uses the default ClientFactory for a typical Baseplate Thrift Client.
func NewTTLClientFactory ¶
func NewTTLClientFactory(ttl time.Duration) ClientFactory
NewTTLClientFactory returns a ClientFactory that creates TTLClients using the given TClientFactory.
Services should generally not have to use NewTTLClientFactory directly, instead you should use NewBaseplateClientPool which uses the default ClientFactory for a typical Baseplate Thrift Client.
type ClientPool ¶
type ClientPool interface {
// Passthrough APIs from clientpool.Pool:
io.Closer
IsExhausted() bool
// GetClient returns a Client from the pool or creates a new one if
// needed.
GetClient() (Client, error)
// ReleaseClient returns the given client to the pool.
ReleaseClient(Client)
}
ClientPool defines an object that can be used to manage a pool of Client objects.
func NewBaseplateClientPool ¶
func NewBaseplateClientPool(cfg ClientPoolConfig, ttl time.Duration, middlewares ...thrift.ClientMiddleware) (ClientPool, error)
NewBaseplateClientPool returns a standard, baseplate ClientPool.
A baseplate ClientPool:
1. Uses a TTLClientPool with the given ttl.
2. Wraps the TClient objects with BaseplateDefaultClientMiddlewares plus any additional client middlewares passed into this function.
func NewCustomClientPool ¶
func NewCustomClientPool( cfg ClientPoolConfig, genAddr AddressGenerator, clientFactory ClientFactory, tClientFactory TClientFactory, protoFactory thrift.TProtocolFactory, ) (ClientPool, error)
NewCustomClientPool creates a ClientPool that uses a custom AddressGenerator and ClientFactory.
Most services will want to just use NewBaseplateClientPool, this has been provided to support services that have non-standard and/or legacy needs.
type ClientPoolConfig ¶
type ClientPoolConfig struct {
// ServiceSlug is a short identifier for the thrift service you are creating
// clients for. The preferred convention is to take the service's name,
// remove the 'Service' prefix, if present, and convert from camel case to
// all lower case, hyphen separated.
//
// Examples:
//
// AuthenticationService -> authentication
// ImageUploadService -> image-upload
ServiceSlug string
// Addr is the address of a thrift service. Addr must be in the format
// "${host}:${port}"
Addr string
// InitialConnections is the inital number of thrift connections created by
// the client pool.
InitialConnections int
// MinConnections is the maximum number of thrift connections the client
// pool can maintain.
MaxConnections int
// SocketTimeout is the timeout on the underling thrift.TSocket.
SocketTimeout time.Duration
// Any labels that should be applied to metrics logged by the ClientPool.
// This includes the optional pool stats.
MetricsLabels metricsbp.Labels
// ReportPoolStats signals to the ClientPool that it should report
// statistics on the underlying clientpool.Pool in a background
// goroutine. If this is set to false, the reporting goroutine will
// not be started and it will not report pool stats.
//
// It reports:
// - the number of active clients to a gauge named
// "${ServiceSlug}.pool-active-connections".
// - the number of allocated clients to a gauge named
// "${ServiceSlug}.pool-allocated-clients".
//
// The reporting goroutine is cancelled when the global metrics client
// context is Done.
ReportPoolStats bool
// PoolGaugeInterval indicates how often we should update the active
// connections gauge when collecting pool stats.
//
// When PoolGaugeInterval <= 0 and ReportPoolStats is true,
// DefaultPoolGaugeInterval will be used instead.
PoolGaugeInterval time.Duration
}
ClientPoolConfig is the configuration struct for creating a new ClientPool.
type MockClient ¶
type MockClient struct {
FailUnregisteredMethods bool
// contains filtered or unexported fields
}
MockClient implements thrift.TClient and Client, and can be used to mock out thrift calls in testing by using it as the base client rather than a real client.
If a MockCall is registered to a method, then Call will return the result of that MockCall when that method is Call-ed. If no MockCall is registered to a method, Call will simply return nil when FailUnregisteredMethods is false, or an error when FailUnregisteredMethods is true.
MockClient is provided to help with unit testing and should not be used in production code.
func (*MockClient) AddMockCall ¶
func (c *MockClient) AddMockCall(method string, mock MockCall)
AddMockCall registers the given MockCall to the given method.
If a mock is already registered to that method, it will be replaced with the new mock.
AddMockCall is not thread-safe.
func (*MockClient) AddNopMockCalls ¶
func (c *MockClient) AddNopMockCalls(methods ...string)
AddNopMockCalls registers the nop MockCall to the given methods.
A nop MockCall is a MockCall implementation that does nothing and returns nil error.
func (*MockClient) Call ¶
Call implements the thrift.TClient interface.
It will return the result of the MockCall registered to method if one exists. If the method is not registered, it returns an error when FailUnregisteredMethods is true, nil otherwise.
func (MockClient) Close ¶
func (MockClient) Close() error
Close implements Client and is a nop that always returns nil.
func (MockClient) IsOpen ¶
func (MockClient) IsOpen() bool
IsOpen implements Client and is a nop that always returns true.
type MockClientPool ¶
MockClientPool is a ClientPool implementation can be used in test code.
func (MockClientPool) Close ¶
func (MockClientPool) Close() error
Close is nop and always returns nil error.
func (MockClientPool) GetClient ¶
func (m MockClientPool) GetClient() (Client, error)
GetClient implements ClientPool interface.
If Exhausted is set to true, it returns clientpool.ErrExhausted as the error.
If Exhausted is set to false, it calls CreateClient field if it's set, or return a default MockClient otherwise.
func (MockClientPool) IsExhausted ¶
func (m MockClientPool) IsExhausted() bool
IsExhausted returns Exhausted field.
func (MockClientPool) ReleaseClient ¶
func (MockClientPool) ReleaseClient(Client)
ReleaseClient is nop.
type MockTProcessor ¶
type MockTProcessor struct {
// contains filtered or unexported fields
}
MockTProcessor can be used to create a mock object that fufills the BaseplateProcessor interface in testing.
func NewMockTProcessor ¶
func NewMockTProcessor(tb testing.TB, processorMap map[string]thrift.TProcessorFunction) *MockTProcessor
NewMockTProcessor returns a pointer to a new MockTProcessor object with the internal processor map initialized to the one passed in.
If the passed in map is nil, an empty map will be initialized and passed in to the new object so it is safe to add to.
func (*MockTProcessor) AddToProcessorMap ¶
func (p *MockTProcessor) AddToProcessorMap(name string, processorFunc thrift.TProcessorFunction)
AddToProcessorMap adds the given TProcessorFunction to the internal processor map with the given name as the key.
func (*MockTProcessor) Process ¶
func (p *MockTProcessor) Process(ctx context.Context, in, out thrift.TProtocol) (bool, thrift.TException)
Process calls the TProcessorFunction assigned to the "name" set on the context object by SetMockTProcessorName.
If no name is set on the context or there is no TProcessorFunction mapped to that name, the call will fail the test.
func (*MockTProcessor) ProcessorMap ¶
func (p *MockTProcessor) ProcessorMap() map[string]thrift.TProcessorFunction
ProcessorMap returns the internal processor map.
type RecordedCall ¶
type RecordedCall struct {
Ctx context.Context
Method string
// contains filtered or unexported fields
}
RecordedCall records the inputs passed to RecordedClient.RecordedCall.
type RecordedClient ¶
type RecordedClient struct {
// contains filtered or unexported fields
}
RecordedClient implements the thrift.TClient interface and records the inputs to each Call.
RecordedClient is provided to help with unit testing and should not be used in production code.
RecordedClient is not thread-safe.
func NewRecordedClient ¶
func NewRecordedClient(c thrift.TClient) *RecordedClient
NewRecordedClient returns a pointer to a new RecordedClient that wraps the provided client.
func (*RecordedClient) Call ¶
func (c *RecordedClient) Call(ctx context.Context, method string, args, result thrift.TStruct) error
Call fufills the thrift.TClient interface. It will record the inputs to Call and either return the result of the inner client.Call or nil if the inner client is nil.
func (RecordedClient) Calls ¶
func (c RecordedClient) Calls() []RecordedCall
Calls returns a copy of all of recorded Calls.
Calls is not thread-safe and may panic if used across threads if the number of calls changes between the copy buffer being intialized and copied.
type ServerConfig ¶
type ServerConfig struct {
// The endpoint address of your thrift service
Addr string
// The timeout for the underlying thrift.TServerSocket transport.
Timeout time.Duration
// A log wrapper that is used by the TSimpleServer.
//
// It's compatible with log.Wrapper (with an extra typecasting),
// but you should not use log.ErrorWithSentryWrapper for this one,
// as it would log all the network I/O errors,
// which would be too spammy for sentry.
Logger thrift.Logger
}
ServerConfig is the arg struct for NewServer.
type TClientFactory ¶
type TClientFactory func(thrift.TTransport, thrift.TProtocolFactory) thrift.TClient
TClientFactory is used by ClientFactory to create the underlying TClient used by the Baseplate Client.
Services should generally not have to use TClientFactories directly, instead you should use NewBaseplateClientPool which uses the default TClientFactory for a typical Baseplate Thrift Client.
func NewMockTClientFactory ¶
func NewMockTClientFactory(client MockClient) TClientFactory
NewMockTClientFactory returns a TClientFactory that always returns the given MockClient.
func NewWrappedTClientFactory ¶
func NewWrappedTClientFactory(base TClientFactory, middlewares ...thrift.ClientMiddleware) TClientFactory
NewWrappedTClientFactory returns a TClientFactory that returns a standard thrift.TClient wrapped with the given middlewares.
Services should generally not have to use NewWrappedTClientFactory directly, instead you should use NewBaseplateClientPool which uses the default TClientFactory for a typical Baseplate Thrift Client.
type TTLClient ¶
TTLClient is a Client implementation wrapping thrift's TTransport with a TTL.
It's intended to be managed by a ClientPool rather than created directly.
func NewTTLClient ¶
NewTTLClient creates a TTLClient with a thrift TTransport and a ttl.