rpc

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2025 License: MIT Imports: 24 Imported by: 0

Documentation

Overview

Package rpc provides error codes and handling for Connect/gRPC protocols.

Package rpc provides interceptor implementations.

Package rpc provides retry policy support according to gRPC specification.

Package rpc provides retry interceptor implementation.

Package rpc provides the main public API for the hyperway RPC library.

Index

Constants

View Source
const (
	CompressionIdentity = ""     // No compression
	CompressionGzip     = "gzip" // gzip compression
)

Compression algorithms

Variables

This section is empty.

Functions

func ClearHandlerCache

func ClearHandlerCache()

ClearCache clears the handler cache (useful for testing)

func MustRegister

func MustRegister[TIn, TOut any](svc *Service, name string, handler Handler[TIn, TOut])

MustRegister registers a typed method and panics on error (recommended).

func MustRegisterMethod added in v0.1.1

func MustRegisterMethod(svc *Service, methods ...*MethodBuilder)

MustRegisterMethod registers methods using the builder pattern and panics on error.

func NewGateway

func NewGateway(services ...*Service) (http.Handler, error)

NewGateway creates a gateway for the service.

func Register

func Register[TIn, TOut any](svc *Service, name string, handler Handler[TIn, TOut]) error

Register registers a typed method (recommended).

func RegisterCompressor

func RegisterCompressor(c Compressor)

RegisterCompressor registers a compressor

func RegisterMethod added in v0.1.1

func RegisterMethod(svc *Service, methods ...*MethodBuilder) error

RegisterMethod registers a method using the builder pattern.

func ValidateRetryPolicy

func ValidateRetryPolicy(policy *RetryPolicy) error

ValidateRetryPolicy validates a retry policy according to gRPC spec.

func ValidateRetryThrottling

func ValidateRetryThrottling(throttling *RetryThrottling) error

ValidateRetryThrottling validates retry throttling configuration.

Types

type Code

type Code string

Code represents a Connect/gRPC error code.

const (
	CodeCanceled           Code = "canceled"
	CodeUnknown            Code = "unknown"
	CodeInvalidArgument    Code = "invalid_argument"
	CodeDeadlineExceeded   Code = "deadline_exceeded"
	CodeNotFound           Code = "not_found"
	CodeAlreadyExists      Code = "already_exists"
	CodePermissionDenied   Code = "permission_denied"
	CodeResourceExhausted  Code = "resource_exhausted"
	CodeFailedPrecondition Code = "failed_precondition"
	CodeAborted            Code = "aborted"
	CodeOutOfRange         Code = "out_of_range"
	CodeUnimplemented      Code = "unimplemented"
	CodeInternal           Code = "internal"
	CodeUnavailable        Code = "unavailable"
	CodeDataLoss           Code = "data_loss"
	CodeUnauthenticated    Code = "unauthenticated"
)

Standard Connect/gRPC error codes.

func (Code) HTTPStatusCode

func (c Code) HTTPStatusCode() int

HTTPStatusCode returns the HTTP status code for the error code. For Connect protocol, most errors return 200 OK with error in body. This is used for non-Connect protocol responses.

type Compressor

type Compressor interface {
	Compress(data []byte) ([]byte, error)
	Decompress(data []byte) ([]byte, error)
	Name() string
}

Compressor interface for compression algorithms

func GetCompressor

func GetCompressor(name string) (Compressor, bool)

GetCompressor returns a compressor by name

type Error

type Error struct {
	Code    Code           `json:"code"`
	Message string         `json:"message"`
	Details map[string]any `json:"details,omitempty"`
}

Error represents a Connect/gRPC error with code and message.

func ErrDeadlineExceeded

func ErrDeadlineExceeded(message string) *Error

ErrDeadlineExceeded creates a deadline exceeded error.

func ErrInternal

func ErrInternal(message string) *Error

ErrInternal creates an internal error.

func ErrInvalidArgument

func ErrInvalidArgument(message string) *Error

ErrInvalidArgument creates an invalid argument error.

func ErrNotFound

func ErrNotFound(message string) *Error

ErrNotFound creates a not found error.

func ErrPermissionDenied

func ErrPermissionDenied(message string) *Error

ErrPermissionDenied creates a permission denied error.

func ErrUnauthenticated

func ErrUnauthenticated(message string) *Error

ErrUnauthenticated creates an unauthenticated error.

func ErrUnimplemented

func ErrUnimplemented(message string) *Error

ErrUnimplemented creates an unimplemented error.

func NewError

func NewError(code Code, message string) *Error

NewError creates a new Error with the given code and message.

func NewErrorf

func NewErrorf(code Code, format string, args ...any) *Error

NewErrorf creates a new Error with the given code and formatted message.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface.

func (*Error) WithDetails

func (e *Error) WithDetails(details map[string]any) *Error

WithDetails adds details to the error.

type GzipCompressor

type GzipCompressor struct{}

GzipCompressor implements gzip compression

func (*GzipCompressor) Compress

func (g *GzipCompressor) Compress(data []byte) ([]byte, error)

func (*GzipCompressor) Decompress

func (g *GzipCompressor) Decompress(data []byte) ([]byte, error)

func (*GzipCompressor) Name

func (g *GzipCompressor) Name() string

type Handler

type Handler[TIn, TOut any] func(context.Context, *TIn) (*TOut, error)

Handler represents a typed RPC handler function.

type HandlerCache

type HandlerCache struct {
	// contains filtered or unexported fields
}

HandlerCache caches pre-computed handler information

type HandlerFunc

type HandlerFunc func(context.Context, any) (any, error)

HandlerFunc is the signature for RPC handlers.

type HandlerInfo

type HandlerInfo struct {
	HandlerValue reflect.Value
	HandlerType  reflect.Type
	InputType    reflect.Type
	OutputType   reflect.Type
	IsPointer    bool // Whether handler expects pointer input
}

HandlerInfo holds pre-computed handler information

func GetHandlerInfo

func GetHandlerInfo(handler any) (*HandlerInfo, error)

GetHandlerInfo returns cached handler information or computes it

type Interceptor

type Interceptor interface {
	// Intercept wraps the handler call.
	Intercept(ctx context.Context, method string, req any, handler func(context.Context, any) (any, error)) (any, error)
}

Interceptor is our own interceptor interface that works with dynamic types.

func ChainInterceptors

func ChainInterceptors(interceptors ...Interceptor) Interceptor

ChainInterceptors chains multiple interceptors into a single interceptor.

type LoggingInterceptor

type LoggingInterceptor struct {
	Logger *log.Logger
}

LoggingInterceptor logs requests and responses.

func (*LoggingInterceptor) Intercept

func (l *LoggingInterceptor) Intercept(ctx context.Context, method string, req any, handler func(context.Context, any) (any, error)) (any, error)

type Method

type Method struct {
	Name       string
	Handler    any
	InputType  reflect.Type
	OutputType reflect.Type
	Options    MethodOptions
}

Method represents an RPC method.

type MethodBuilder

type MethodBuilder struct {
	// contains filtered or unexported fields
}

MethodBuilder provides a fluent API for building methods.

func NewMethod

func NewMethod[TIn, TOut any](name string, handler Handler[TIn, TOut]) *MethodBuilder

NewMethod creates a new method.

func (*MethodBuilder) Build

func (m *MethodBuilder) Build() *Method

Build returns the built method.

func (*MethodBuilder) In

func (m *MethodBuilder) In(example any) *MethodBuilder

In sets the input type.

func (*MethodBuilder) Out

func (m *MethodBuilder) Out(example any) *MethodBuilder

Out sets the output type.

func (*MethodBuilder) Validate

func (m *MethodBuilder) Validate(enabled bool) *MethodBuilder

Validate sets whether to validate input.

func (*MethodBuilder) WithDescription

func (m *MethodBuilder) WithDescription(description string) *MethodBuilder

WithDescription sets the method description for documentation.

func (*MethodBuilder) WithInterceptors

func (m *MethodBuilder) WithInterceptors(interceptors ...Interceptor) *MethodBuilder

WithInterceptors adds interceptors to the method.

type MethodConfig

type MethodConfig struct {
	// Name identifies the methods to which this configuration applies.
	Name []MethodName `json:"name"`

	// Timeout for the method. Format: "1s", "100ms", etc.
	Timeout string `json:"timeout,omitempty"`

	// RetryPolicy for the method.
	RetryPolicy *RetryPolicy `json:"retryPolicy,omitempty"`
}

MethodConfig defines the configuration for specific methods.

type MethodName

type MethodName struct {
	// Service name including proto package name. Required.
	Service string `json:"service"`

	// Method name. If empty, applies to all methods in the service.
	Method string `json:"method,omitempty"`
}

MethodName identifies a gRPC method.

type MethodOptions

type MethodOptions struct {
	// Validate enables input validation for this method
	Validate *bool
	// Interceptors specific to this method
	Interceptors []Interceptor
	// Description is the method-level documentation
	Description string
}

MethodOptions configures a method.

type MetricsInterceptor

type MetricsInterceptor struct {
	RequestCount  int64
	SuccessCount  int64
	FailureCount  int64
	TotalDuration time.Duration
}

MetricsInterceptor collects metrics.

func (*MetricsInterceptor) Intercept

func (m *MetricsInterceptor) Intercept(ctx context.Context, method string, req any, handler func(context.Context, any) (any, error)) (any, error)

type RecoveryInterceptor

type RecoveryInterceptor struct{}

RecoveryInterceptor recovers from panics.

func (*RecoveryInterceptor) Intercept

func (r *RecoveryInterceptor) Intercept(ctx context.Context, method string, req any, handler func(context.Context, any) (any, error)) (resp any, err error)

type RetryInterceptor

type RetryInterceptor struct {
	// contains filtered or unexported fields
}

RetryInterceptor implements retry logic according to gRPC specification.

func DefaultRetryInterceptor

func DefaultRetryInterceptor() *RetryInterceptor

DefaultRetryInterceptor creates a retry interceptor with default retry policy.

func NewRetryInterceptor

func NewRetryInterceptor(config *ServiceConfig) *RetryInterceptor

NewRetryInterceptor creates a new retry interceptor with the given service config.

func (*RetryInterceptor) Intercept

func (r *RetryInterceptor) Intercept(
	ctx context.Context,
	method string,
	req any,
	handler func(context.Context, any) (any, error),
) (any, error)

Intercept implements the Interceptor interface with retry logic.

type RetryPolicy

type RetryPolicy struct {
	// MaxAttempts is the maximum number of attempts including the original request.
	// Must be greater than 1. Required.
	MaxAttempts int `json:"maxAttempts"`

	// InitialBackoff is the initial delay before the first retry.
	// Format: "0.1s", "100ms", etc.
	InitialBackoff string `json:"initialBackoff"`

	// MaxBackoff is the maximum delay between retries.
	// Format: "30s", "1m", etc.
	MaxBackoff string `json:"maxBackoff"`

	// BackoffMultiplier is the multiplier for exponential backoff.
	// Default: 2.0
	BackoffMultiplier float64 `json:"backoffMultiplier"`

	// RetryableStatusCodes defines which status codes should trigger a retry.
	// Common values: ["UNAVAILABLE"], ["DEADLINE_EXCEEDED"], ["UNAVAILABLE", "RESOURCE_EXHAUSTED"]
	RetryableStatusCodes []string `json:"retryableStatusCodes"`
}

RetryPolicy defines the retry configuration for a method according to gRPC spec.

func AggressiveRetryPolicy

func AggressiveRetryPolicy() *RetryPolicy

AggressiveRetryPolicy returns a more aggressive retry policy for critical operations.

func DefaultRetryPolicy

func DefaultRetryPolicy() *RetryPolicy

DefaultRetryPolicy returns a sensible default retry policy.

type RetryThrottling

type RetryThrottling struct {
	// MaxTokens is the maximum number of tokens in the bucket.
	// Must be in range (0, 1000]. Required.
	MaxTokens int `json:"maxTokens"`

	// TokenRatio is the ratio of tokens to add on each successful RPC.
	// Must be greater than 0. Decimal places beyond 3 are ignored.
	TokenRatio float64 `json:"tokenRatio"`
}

RetryThrottling controls client-side retry throttling.

type Service

type Service struct {
	// contains filtered or unexported fields
}

Service represents an RPC service.

func NewService

func NewService(name string, opts ...ServiceOption) *Service

NewService creates a new RPC service.

func (*Service) ExportAllProtos

func (s *Service) ExportAllProtos() (map[string]string, error)

ExportAllProtos exports all proto files including dependencies.

func (*Service) ExportProto

func (s *Service) ExportProto() (string, error)

ExportProto exports the service definition as a .proto file.

func (*Service) GetFileDescriptorSet

func (s *Service) GetFileDescriptorSet() *descriptorpb.FileDescriptorSet

GetFileDescriptorSet returns the FileDescriptorSet for this service.

func (*Service) Handlers

func (s *Service) Handlers() map[string]http.Handler

Handlers returns the HTTP handlers for all methods.

func (*Service) MustRegister

func (s *Service) MustRegister(method *Method)

MustRegister is like Register but panics on error.

func (*Service) Name

func (s *Service) Name() string

Name returns the service name.

func (*Service) PackageName

func (s *Service) PackageName() string

PackageName returns the service package name.

func (*Service) Register

func (s *Service) Register(method *Method) error

Register adds a method to the service.

type ServiceConfig

type ServiceConfig struct {
	// MethodConfig contains per-method configuration.
	MethodConfig []MethodConfig `json:"methodConfig,omitempty"`

	// RetryThrottling controls client-side retry throttling.
	RetryThrottling *RetryThrottling `json:"retryThrottling,omitempty"`
}

ServiceConfig represents the complete service configuration.

func ParseServiceConfig

func ParseServiceConfig(jsonConfig string) (*ServiceConfig, error)

ParseServiceConfig parses a JSON service configuration.

type ServiceOption

type ServiceOption func(*ServiceOptions)

ServiceOption configures a service.

func WithDescription

func WithDescription(description string) ServiceOption

WithDescription sets the service description for documentation.

func WithEdition

func WithEdition(edition string) ServiceOption

WithEdition enables Protobuf Editions mode with the specified edition.

func WithInterceptors

func WithInterceptors(interceptors ...Interceptor) ServiceOption

WithInterceptors adds interceptors to the service.

func WithPackage

func WithPackage(pkg string) ServiceOption

WithPackage sets the protobuf package name.

func WithReflection

func WithReflection(enabled bool) ServiceOption

WithReflection enables gRPC reflection.

func WithServiceConfig

func WithServiceConfig(jsonConfig string) ServiceOption

WithServiceConfig sets the gRPC service configuration.

func WithValidation

func WithValidation(enabled bool) ServiceOption

WithValidation enables validation by default.

type ServiceOptions

type ServiceOptions struct {
	// Package sets the protobuf package name
	Package string
	// EnableValidation enables input validation by default
	EnableValidation bool
	// EnableReflection enables gRPC reflection
	EnableReflection bool
	// Interceptors to apply to all methods
	Interceptors []Interceptor
	// Edition sets the Protobuf edition (e.g., "2023", "2024")
	Edition string
	// UseEditions enables Protobuf Editions mode instead of proto3
	UseEditions bool
	// ServiceConfig is the gRPC service configuration (JSON string)
	ServiceConfig string
	// Description is the service-level documentation
	Description string
}

ServiceOptions configures a service.

type TimeoutInterceptor

type TimeoutInterceptor struct {
	Timeout time.Duration
}

TimeoutInterceptor adds timeout to requests.

func (*TimeoutInterceptor) Intercept

func (t *TimeoutInterceptor) Intercept(ctx context.Context, method string, req any, handler func(context.Context, any) (any, error)) (any, error)

Jump to

Keyboard shortcuts

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