package gax
import "github.com/googleapis/gax-go/v2"
Package gax contains a set of modules which aid the development of APIs for clients and servers based on gRPC and Google API conventions.
Application code will rarely need to use this library directly. However, code generated automatically from API definition files can use it to simplify code generation and to provide more convenient and idiomatic API surfaces.
Index ¶
- Constants
- Variables
- func BuildHeaders(ctx context.Context, keyvals ...string) http.Header
- func DetermineContentType(media io.Reader) (io.Reader, string)
- func InsertMetadataIntoOutgoingContext(ctx context.Context, keyvals ...string) context.Context
- func Invoke(ctx context.Context, call APICall, opts ...CallOption) error
- func Sleep(ctx context.Context, d time.Duration) error
- func XGoogHeader(keyval ...string) string
- type APICall
- type Backoff
- type CallOption
- func WithGRPCOptions(opt ...grpc.CallOption) CallOption
- func WithPath(p string) CallOption
- func WithRetry(fn func() Retryer) CallOption
- func WithTimeout(t time.Duration) CallOption
- type CallSettings
- type ProtoJSONStream
- func NewProtoJSONStreamReader(rc io.ReadCloser, typ protoreflect.MessageType) *ProtoJSONStream
- func (s *ProtoJSONStream) Close() error
- func (s *ProtoJSONStream) Recv() (proto.Message, error)
- type Retryer
Examples ¶
Constants ¶
Version specifies the gax-go version being used.
Variables ¶
var ( // GoVersion is a header-safe representation of the current runtime // environment's Go version. This is for GAX consumers that need to // report the Go runtime version in API calls. GoVersion string )
Functions ¶
func BuildHeaders ¶
BuildHeaders is for use by the Google Cloud Libraries only. See package github.com/googleapis/gax-go/v2/callctx for help setting/retrieving request/response headers.
BuildHeaders returns a new http.Header that merges the provided keyvals header pairs with any existing metadata/headers in the provided context. keyvals should have a corresponding value for every key provided. If there is an odd number of keyvals this method will panic. Existing values for keys will not be overwritten, instead provided values will be appended to the list of existing values.
func DetermineContentType ¶
DetermineContentType determines the content type of the supplied reader. The content of media will be sniffed to determine the content type. After calling DetectContentType the caller must not perform further reads on media, but rather read from the Reader that is returned.
func InsertMetadataIntoOutgoingContext ¶
InsertMetadataIntoOutgoingContext is for use by the Google Cloud Libraries only. See package github.com/googleapis/gax-go/v2/callctx for help setting/retrieving request/response headers.
InsertMetadataIntoOutgoingContext returns a new context that merges the provided keyvals metadata pairs with any existing metadata/headers in the provided context. keyvals should have a corresponding value for every key provided. If there is an odd number of keyvals this method will panic. Existing values for keys will not be overwritten, instead provided values will be appended to the list of existing values.
func Invoke ¶
func Invoke(ctx context.Context, call APICall, opts ...CallOption) error
Invoke calls the given APICall, performing retries as specified by opts, if
any.
Code:play
Code:play
Example (Grpc)¶
package main
import (
"context"
"time"
gax "github.com/googleapis/gax-go/v2"
"google.golang.org/grpc/codes"
)
// Some result that the client might return.
type fakeResponse struct{}
// Some client that can perform RPCs.
type fakeClient struct{}
// PerformSomeRPC is a fake RPC that a client might perform.
func (c *fakeClient) PerformSomeRPC(ctx context.Context) (*fakeResponse, error) {
return nil, nil
}
func main() {
ctx := context.Background()
c := &fakeClient{}
opt := gax.WithRetry(func() gax.Retryer {
return gax.OnCodes([]codes.Code{codes.Unknown, codes.Unavailable}, gax.Backoff{
Initial: time.Second,
Max: 32 * time.Second,
Multiplier: 2,
})
})
var resp *fakeResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.PerformSomeRPC(ctx)
return err
}, opt)
if err != nil {
// TODO: handle err
}
_ = resp // TODO: use resp if err is nil
}
Example (Http)¶
package main
import (
"context"
"net/http"
"time"
gax "github.com/googleapis/gax-go/v2"
)
// Some result that the client might return.
type fakeResponse struct{}
// Some client that can perform RPCs.
type fakeClient struct{}
// PerformSomeRPC is a fake RPC that a client might perform.
func (c *fakeClient) PerformSomeRPC(ctx context.Context) (*fakeResponse, error) {
return nil, nil
}
func main() {
ctx := context.Background()
c := &fakeClient{}
opt := gax.WithRetry(func() gax.Retryer {
return gax.OnHTTPCodes(gax.Backoff{
Initial: time.Second,
Max: 32 * time.Second,
Multiplier: 2,
}, http.StatusBadGateway, http.StatusServiceUnavailable)
})
var resp *fakeResponse
err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
var err error
resp, err = c.PerformSomeRPC(ctx)
return err
}, opt)
if err != nil {
// TODO: handle err
}
_ = resp // TODO: use resp if err is nil
}
func Sleep ¶
Sleep is similar to time.Sleep, but it can be interrupted by ctx.Done() closing. If interrupted, Sleep returns ctx.Err().
func XGoogHeader ¶
XGoogHeader is for use by the Google Cloud Libraries only. See package github.com/googleapis/gax-go/v2/callctx for help setting/retrieving request/response headers.
XGoogHeader formats key-value pairs. The resulting string is suitable for x-goog-api-client header.
Types ¶
type APICall ¶
type APICall func(context.Context, CallSettings) error
APICall is a user defined call stub.
type Backoff ¶
type Backoff struct { // Initial is the initial value of the retry period, defaults to 1 second. Initial time.Duration // Max is the maximum value of the retry period, defaults to 30 seconds. Max time.Duration // Multiplier is the factor by which the retry period increases. // It should be greater than 1 and defaults to 2. Multiplier float64 // contains filtered or unexported fields }
Backoff implements exponential backoff. The wait time between retries is a random value between 0 and the "retry period" - the time between retries. The retry period starts at Initial and increases by the factor of Multiplier every retry, but is capped at Max.
Note: MaxNumRetries / RPCDeadline is specifically not provided. These should
be built on top of Backoff.
Code:play
Example¶
package main
import (
"context"
"net/http"
"time"
gax "github.com/googleapis/gax-go/v2"
)
func main() {
ctx := context.Background()
bo := gax.Backoff{
Initial: time.Second,
Max: time.Minute, // Maximum amount of time between retries.
Multiplier: 2,
}
performHTTPCallWithRetry := func(ctx context.Context, doHTTPCall func(ctx context.Context) (*http.Response, error)) (*http.Response, error) {
for {
resp, err := doHTTPCall(ctx)
if err != nil {
// Retry 503 UNAVAILABLE.
if resp.StatusCode == http.StatusServiceUnavailable {
if err := gax.Sleep(ctx, bo.Pause()); err != nil {
return nil, err
}
continue
}
return nil, err
}
return resp, err
}
}
// It's recommended to set deadlines on HTTP calls and around retrying. This
// is also usually preferred over setting some fixed number of retries: one
// advantage this has is that backoff settings can be changed independently
// of the deadline, whereas with a fixed number of retries the deadline
// would be a constantly-shifting goalpost.
ctxWithTimeout, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute))
defer cancel()
resp, err := performHTTPCallWithRetry(ctxWithTimeout, func(ctx context.Context) (*http.Response, error) {
req, err := http.NewRequest("some-method", "example.com", nil)
if err != nil {
return nil, err
}
req = req.WithContext(ctx)
return http.DefaultClient.Do(req)
})
if err != nil {
// TODO: handle err
}
_ = resp // TODO: use resp if err is nil
}
func (*Backoff) Pause ¶
Pause returns the next time.Duration that the caller should use to backoff.
type CallOption ¶
type CallOption interface { // Resolve applies the option by modifying cs. Resolve(cs *CallSettings) }
CallOption is an option used by Invoke to control behaviors of RPC calls. CallOption works by modifying relevant fields of CallSettings.
func WithGRPCOptions ¶
func WithGRPCOptions(opt ...grpc.CallOption) CallOption
WithGRPCOptions allows passing gRPC call options during client creation.
func WithPath ¶
func WithPath(p string) CallOption
WithPath applies a Path override to the HTTP-based APICall.
This is for internal use only.
func WithRetry ¶
func WithRetry(fn func() Retryer) CallOption
WithRetry sets CallSettings.Retry to fn.
func WithTimeout ¶
func WithTimeout(t time.Duration) CallOption
WithTimeout is a convenience option for setting a context.WithTimeout on the singular context.Context used for **all** APICall attempts. Calculated from the start of the first APICall attempt. If the context.Context provided to Invoke already has a Deadline set, that will always be respected over the deadline calculated using this option.
type CallSettings ¶
type CallSettings struct { // Retry returns a Retryer to be used to control retry logic of a method call. // If Retry is nil or the returned Retryer is nil, the call will not be retried. Retry func() Retryer // CallOptions to be forwarded to GRPC. GRPC []grpc.CallOption // Path is an HTTP override for an APICall. Path string // contains filtered or unexported fields }
CallSettings allow fine-grained control over how calls are made.
type ProtoJSONStream ¶
type ProtoJSONStream struct {
// contains filtered or unexported fields
}
ProtoJSONStream represents a wrapper for consuming a stream of protobuf messages encoded using protobuf-JSON format. More information on this format can be found at https://developers.google.com/protocol-buffers/docs/proto3#json. The stream must appear as a comma-delimited, JSON array of obbjects with opening and closing square braces.
This is for internal use only.
Code:play
Example¶
package main
import (
"io"
"net/http"
gax "github.com/googleapis/gax-go/v2"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/types/known/structpb"
)
func main() {
var someHTTPCall func() (http.Response, error)
res, err := someHTTPCall()
if err != nil {
// TODO: handle err
}
// The type of message expected in the stream.
var typ protoreflect.MessageType = (&structpb.Struct{}).ProtoReflect().Type()
stream := gax.NewProtoJSONStreamReader(res.Body, typ)
defer stream.Close()
for {
m, err := stream.Recv()
if err != nil {
break
}
// TODO: use resp
_ = m.(*structpb.Struct)
}
if err != io.EOF {
// TODO: handle err
}
}
func NewProtoJSONStreamReader ¶
func NewProtoJSONStreamReader(rc io.ReadCloser, typ protoreflect.MessageType) *ProtoJSONStream
NewProtoJSONStreamReader accepts a stream of bytes via an io.ReadCloser that are protobuf-JSON encoded protobuf messages of the given type. The ProtoJSONStream must be closed when done.
This is for internal use only.
func (*ProtoJSONStream) Close ¶
func (s *ProtoJSONStream) Close() error
Close closes the stream so that resources are cleaned up.
func (*ProtoJSONStream) Recv ¶
func (s *ProtoJSONStream) Recv() (proto.Message, error)
Recv decodes the next protobuf message in the stream or returns io.EOF if the stream is done. It is not safe to call Recv on the same stream from different goroutines, just like it is not safe to do so with a single gRPC stream. Type-cast the protobuf message returned to the type provided at ProtoJSONStream creation. Calls to Recv after calling Close will produce io.EOF.
type Retryer ¶
type Retryer interface { // Retry reports whether a request should be retried and how long to pause before retrying // if the previous attempt returned with err. Invoke never calls Retry with nil error. Retry(err error) (pause time.Duration, shouldRetry bool) }
Retryer is used by Invoke to determine retry behavior.
func OnCodes ¶
OnCodes returns a Retryer that retries if and only if the previous attempt returns a GRPC error whose error code is stored in cc. Pause times between retries are specified by bo.
bo is only used for its parameters; each Retryer has its own copy.
Code:play
Example¶
package main
import (
"context"
"time"
gax "github.com/googleapis/gax-go/v2"
"google.golang.org/grpc/codes"
)
// Some result that the client might return.
type fakeResponse struct{}
// Some client that can perform RPCs.
type fakeClient struct{}
// PerformSomeRPC is a fake RPC that a client might perform.
func (c *fakeClient) PerformSomeRPC(ctx context.Context) (*fakeResponse, error) {
return nil, nil
}
func main() {
ctx := context.Background()
c := &fakeClient{}
// UNKNOWN and UNAVAILABLE are typically safe to retry for idempotent RPCs.
retryer := gax.OnCodes([]codes.Code{codes.Unknown, codes.Unavailable}, gax.Backoff{
Initial: time.Second,
Max: 32 * time.Second,
Multiplier: 2,
})
performSomeRPCWithRetry := func(ctx context.Context) (*fakeResponse, error) {
for {
resp, err := c.PerformSomeRPC(ctx)
if err != nil {
if delay, shouldRetry := retryer.Retry(err); shouldRetry {
if err := gax.Sleep(ctx, delay); err != nil {
return nil, err
}
continue
}
return nil, err
}
return resp, err
}
}
// It's recommended to set deadlines on RPCs and around retrying. This is
// also usually preferred over setting some fixed number of retries: one
// advantage this has is that backoff settings can be changed independently
// of the deadline, whereas with a fixed number of retries the deadline
// would be a constantly-shifting goalpost.
ctxWithTimeout, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute))
defer cancel()
resp, err := performSomeRPCWithRetry(ctxWithTimeout)
if err != nil {
// TODO: handle err
}
_ = resp // TODO: use resp if err is nil
}
func OnErrorFunc ¶
OnErrorFunc returns a Retryer that retries if and only if the previous attempt returns an error that satisfies shouldRetry.
Pause times between retries are specified by bo. bo is only used for its
parameters; each Retryer has its own copy.
Code:play
Example¶
package main
import (
"context"
"time"
gax "github.com/googleapis/gax-go/v2"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// Some result that the client might return.
type fakeResponse struct{}
// Some client that can perform RPCs.
type fakeClient struct{}
// PerformSomeRPC is a fake RPC that a client might perform.
func (c *fakeClient) PerformSomeRPC(ctx context.Context) (*fakeResponse, error) {
return nil, nil
}
func main() {
ctx := context.Background()
c := &fakeClient{}
shouldRetryUnavailableUnKnown := func(err error) bool {
st, ok := status.FromError(err)
if !ok {
return false
}
return st.Code() == codes.Unavailable || st.Code() == codes.Unknown
}
retryer := gax.OnErrorFunc(gax.Backoff{
Initial: time.Second,
Max: 32 * time.Second,
Multiplier: 2,
}, shouldRetryUnavailableUnKnown)
performSomeRPCWithRetry := func(ctx context.Context) (*fakeResponse, error) {
for {
resp, err := c.PerformSomeRPC(ctx)
if err != nil {
if delay, shouldRetry := retryer.Retry(err); shouldRetry {
if err := gax.Sleep(ctx, delay); err != nil {
return nil, err
}
continue
}
return nil, err
}
return resp, err
}
}
// It's recommended to set deadlines on RPCs and around retrying. This is
// also usually preferred over setting some fixed number of retries: one
// advantage this has is that backoff settings can be changed independently
// of the deadline, whereas with a fixed number of retries the deadline
// would be a constantly-shifting goalpost.
ctxWithTimeout, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute))
defer cancel()
resp, err := performSomeRPCWithRetry(ctxWithTimeout)
if err != nil {
// TODO: handle err
}
_ = resp // TODO: use resp if err is nil
}
func OnHTTPCodes ¶
OnHTTPCodes returns a Retryer that retries if and only if the previous attempt returns a googleapi.Error whose status code is stored in cc. Pause times between retries are specified by bo.
bo is only used for its parameters; each Retryer has its own copy.
Code:play
Example¶
package main
import (
"context"
"net/http"
"time"
gax "github.com/googleapis/gax-go/v2"
)
// Some result that the client might return.
type fakeResponse struct{}
// Some client that can perform RPCs.
type fakeClient struct{}
// PerformSomeRPC is a fake RPC that a client might perform.
func (c *fakeClient) PerformSomeRPC(ctx context.Context) (*fakeResponse, error) {
return nil, nil
}
func main() {
ctx := context.Background()
c := &fakeClient{}
retryer := gax.OnHTTPCodes(gax.Backoff{
Initial: time.Second,
Max: 32 * time.Second,
Multiplier: 2,
}, http.StatusBadGateway, http.StatusServiceUnavailable)
performSomeRPCWithRetry := func(ctx context.Context) (*fakeResponse, error) {
for {
resp, err := c.PerformSomeRPC(ctx)
if err != nil {
if delay, shouldRetry := retryer.Retry(err); shouldRetry {
if err := gax.Sleep(ctx, delay); err != nil {
return nil, err
}
continue
}
return nil, err
}
return resp, err
}
}
// It's recommended to set deadlines on RPCs and around retrying. This is
// also usually preferred over setting some fixed number of retries: one
// advantage this has is that backoff settings can be changed independently
// of the deadline, whereas with a fixed number of retries the deadline
// would be a constantly-shifting goalpost.
ctxWithTimeout, cancel := context.WithDeadline(ctx, time.Now().Add(5*time.Minute))
defer cancel()
resp, err := performSomeRPCWithRetry(ctxWithTimeout)
if err != nil {
// TODO: handle err
}
_ = resp // TODO: use resp if err is nil
}
Source Files ¶
call_option.go content_type.go gax.go header.go invoke.go proto_json_stream.go
Directories ¶
Path | Synopsis |
---|---|
apierror | Package apierror implements a wrapper error for parsing error details from API calls. |
apierror/internal | |
callctx | Package callctx provides helpers for storing and retrieving values out of context.Context. |
internal | |
internallog | Package internallog in intended for internal use by generated clients only. |
internallog/grpclog | Package grpclog in intended for internal use by generated clients only. |
internallog/internal | Package internal provides some common logic and types to other logging sub-packages. |
iterator | Package iterator contains helper for working with iterators. |
- Version
- v2.14.1 (latest)
- Published
- Dec 20, 2024
- Platform
- linux/amd64
- Imports
- 24 packages
- Last checked
- 6 hours ago –
Tools for package owners.