pool

package
v0.4.2 Latest Latest
Warning

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

Go to latest
Published: Jan 4, 2025 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	RetryAfter    = "Retry-After"
	RetryAfterSec = 5
)

Retry header constants define the retry mechanism configuration.

View Source
const (
	StatusMovedPermanently  = http.StatusMovedPermanently
	StatusFound             = http.StatusFound
	StatusSeeOther          = http.StatusSeeOther
	StatusTemporaryRedirect = http.StatusTemporaryRedirect
	StatusPermanentRedirect = http.StatusPermanentRedirect

	HeaderServer         = "Server"           // The Server header identifies the server software handling the request.
	HeaderXPoweredBy     = "X-Powered-By"     // The X-Powered-By header indicates technologies supporting the server.
	HeaderXProxyBy       = "X-Proxy-By"       // The X-Proxy-By header identifies the proxy handling the request.
	HeaderLocation       = "Location"         // The Location header is used in redirection or when a new resource has been created.
	HeaderXForwardedFor  = "X-Forwarded-For"  // The X-Forwarded-For header identifies the originating IP address of a client connecting to a web server through a proxy.
	HeaderXForwardedHost = "X-Forwarded-Host" // The X-Forwarded-Host header identifies the original host requested by the client.
	HeaderHost           = "Host"             // The Host header specifies the domain name of the server and the TCP port number on which the server is listening.

	DefaultScheme     = "http"
	DefaultProxyLabel = "terraster"
)

Constants representing various HTTP status codes used for redirection.

View Source
const (
	// RetryKey is used as a key to store and retrieve retry counts from the request context.
	RetryKey contextKey = iota
)

Variables

View Source
var (
	ErrBackendUnavailable = errors.New("server unavailable")
	ErrBackendTimeout     = errors.New("server timeout")
	ErrInvalidRedirect    = errors.New("invalid redirect received from server")
)

Common proxy error types

Functions

func GetRetryFromContext

func GetRetryFromContext(r *http.Request) int

GetRetryFromContext extracts the retry count from the request's context. If no retry count is present, it returns 0. This is used to track the number of retry attempts for a given request.

func IsTemporaryError added in v0.4.2

func IsTemporaryError(err error) bool

IsTemporaryError determines if an error is temporary and the request can be retried

func WriteErrorResponse added in v0.4.2

func WriteErrorResponse(w http.ResponseWriter, err error)

WriteErrorResponse writes a structured error response to the client

Types

type Backend

type Backend struct {
	URL             *url.URL                  // The URL of the backend server, including scheme, host, and port.
	Host            string                    // The hostname extracted from the URL, used for logging and identification.
	Alive           atomic.Bool               // Atomic flag indicating whether the backend is currently alive and reachable.
	Weight          int                       // The weight assigned to the backend for load balancing purposes.
	CurrentWeight   atomic.Int32              // The current weight used in certain load balancing algorithms (e.g., weighted round-robin).
	Proxy           *URLRewriteProxy          // The proxy instance responsible for handling HTTP requests to this backend.
	ConnectionCount int32                     // The current number of active connections to this backend.
	MaxConnections  int32                     // The maximum number of concurrent connections allowed to this backend.
	SuccessCount    int32                     // The total number of successful requests processed by this backend.
	FailureCount    int32                     // The total number of failed requests processed by this backend.
	HealthCheckCfg  *config.HealthCheckConfig // Configuration settings for health checks specific to this backend.
}

func (*Backend) DecrementConnections

func (b *Backend) DecrementConnections()

DecrementConnections decrements the active connection count for the backend. This should be called when a connection to the backend is closed or terminated. It ensures that the connection count accurately reflects the current load.

func (*Backend) GetConnectionCount

func (b *Backend) GetConnectionCount() int

GetConnectionCount returns the current number of active connections to the backend.

func (*Backend) GetCurrentWeight

func (b *Backend) GetCurrentWeight() int

GetCurrentWeight fetches the current weight of the backend.

func (*Backend) GetURL

func (b *Backend) GetURL() string

GetURL returns the string representation of the backend's URL.

func (*Backend) GetWeight

func (b *Backend) GetWeight() int

GetWeight retrieves the current weight assigned to the backend. The weight influences the load balancing decision, determining the proportion of traffic this backend receives.

func (*Backend) IncrementConnections

func (b *Backend) IncrementConnections() bool

IncrementConnections attempts to increment the active connection count for the backend. It ensures that the connection count does not exceed the maximum allowed. Returns true if the increment was successful, or false if the backend is at maximum capacity.

func (*Backend) IsAlive

func (b *Backend) IsAlive() bool

IsAlive checks whether the backend is currently marked as alive. An alive backend is considered healthy and eligible to receive traffic.

func (*Backend) SetAlive added in v0.1.4

func (b *Backend) SetAlive(alive bool)

SetAlive updates the alive status of the backend.

func (*Backend) SetCurrentWeight

func (b *Backend) SetCurrentWeight(weight int)

SetCurrentWeight sets the current weight of the backend to the specified value.

type BackendSnapshot added in v0.1.5

type BackendSnapshot struct {
	Backends     []*Backend          // Slice of all backend servers in the pool.
	BackendCache map[string]*Backend // Map for quick access to backends by their URL string.
}

BackendSnapshot represents a snapshot of the current state of backends in the ServerPool.

type BufferPool

type BufferPool struct {
	sync.Pool
}

BufferPool is a wrapper around sync.Pool that provides a pool of reusable byte slices.

func NewBufferPool

func NewBufferPool() *BufferPool

NewBufferPool initializes and returns a new instance of BufferPool. It sets up the underlying sync.Pool with a default byte slice size of 32KB.

func (*BufferPool) Get

func (b *BufferPool) Get() []byte

Get retrieves a byte slice from the BufferPool. If the pool is empty, it allocates a new byte slice using the New function defined in NewBufferPool.

func (*BufferPool) Put

func (b *BufferPool) Put(buf []byte)

Put returns a byte slice back to the BufferPool for reuse. By recycling buffers, the application can significantly reduce memory fragmentation and garbage collection pressure.

type ConnectionPool

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

ConnectionPool manages a pool of HTTP clients to efficiently handle multiple HTTP requests. Controls the number of idle and open connections, ensuring optimal resource usage and performance.

func NewConnectionPool

func NewConnectionPool(maxIdle, maxOpen int, idleTimeout time.Duration) *ConnectionPool

NewConnectionPool initializes and returns a new instance of ConnectionPool. Sets up the pool with specified maximum idle and open connections, and an idle timeout duration.

func (*ConnectionPool) Get

func (p *ConnectionPool) Get() *http.Client

Get retrieves an HTTP client from the ConnectionPool. If an idle client is available in the pool, it returns that client. If no idle clients are available and the number of open clients is below maxOpen, it creates a new HTTP client, increments the open client count, and returns the new client. If the pool has reached its maximum number of open clients, it waits until a client becomes available.

func (*ConnectionPool) Put

func (p *ConnectionPool) Put(client *http.Client)

Put returns an HTTP client back to the ConnectionPool after use. If the pool has not reached its maximum number of idle clients, the client is placed back into the pool for reuse. If the pool is already full, the client is discarded, and the count of open clients is decremented accordingly.

type ErrorResponse added in v0.4.2

type ErrorResponse struct {
	Status     string `json:"status"`
	Message    string `json:"message"`
	RetryAfter int    `json:"retry_after,omitempty"`
}

ErrorResponse represents the structure of error responses sent to clients

type HeaderHandler added in v0.4.2

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

HeaderHandler manages request and response header modifications

func NewHeaderHandler added in v0.4.2

func NewHeaderHandler(cfg config.HeaderConfig) *HeaderHandler

NewHeaderHandler creates a new HeaderHandler

func (*HeaderHandler) ProcessRequestHeaders added in v0.4.2

func (h *HeaderHandler) ProcessRequestHeaders(req *http.Request)

ProcessRequestHeaders modifies the request headers

func (*HeaderHandler) ProcessResponseHeaders added in v0.4.2

func (h *HeaderHandler) ProcessResponseHeaders(resp *http.Response)

ProcessResponseHeaders modifies the response headers

type PoolConfig

type PoolConfig struct {
	Algorithm string `json:"algorithm"`       // The name of the load balancing algorithm to use (e.g., "round-robin").
	MaxConns  int32  `json:"max_connections"` // The maximum number of concurrent connections allowed per backend.
}

type ProxyError

type ProxyError struct {
	Op         string
	Code       ProxyErrorCode
	Message    string
	Err        error
	Retryable  bool
	StatusCode int
}

ProxyError represents a detailed error that occurs during proxy operations

func NewProxyError added in v0.4.2

func NewProxyError(op string, err error) *ProxyError

NewProxyError creates a new ProxyError with appropriate defaults based on the error type

func (*ProxyError) Error

func (e *ProxyError) Error() string

func (*ProxyError) Unwrap added in v0.4.2

func (e *ProxyError) Unwrap() error

type ProxyErrorCode added in v0.4.2

type ProxyErrorCode int

ProxyErrorCode represents specific error conditions in the proxy

const (
	ErrCodeUnknown ProxyErrorCode = iota
	ErrCodeBackendConnFailed
	ErrCodeBackendTimeout
	ErrCodeInvalidResponse
	ErrCodeTLSError
	ErrCodeClientDisconnect
)

type ProxyOption

type ProxyOption func(*URLRewriteProxy)

ProxyOption defines a function type for applying optional configurations to URLRewriteProxy instances.

func WithHeaderConfig added in v0.4.1

func WithHeaderConfig(cfg *config.HeaderConfig) ProxyOption

WithHeaderConfig sets custom req/res headers

func WithLogger

func WithLogger(logger *zap.Logger) ProxyOption

WithLogger is configuring the URLRewriteProxy with a custom logger.

func WithURLRewriter

func WithURLRewriter(config RouteConfig, backendURL *url.URL) ProxyOption

WithURLRewriter is configuring the URLRewriteProxy. It sets up a URL rewriter based on the provided RouteConfig and backend URL. This allows the proxy to modify incoming request URLs according to the specified rewrite rules, ensuring that requests are correctly routed to the intended backend services.

type RewriteConfig

type RewriteConfig struct {
	ProxyPath  string // The path prefix that the proxy should handle and potentially strip from incoming requests.
	RewriteURL string // The URL to which the incoming request's path should be rewritten.
	Redirect   string // The URL to redirect the request to, if redirection is enabled.
}

RewriteConfig holds configuration settings for URL rewriting and redirection. It defines how incoming request paths should be transformed before being forwarded to the backend services.

type RouteConfig

type RouteConfig struct {
	Path          string // Path is the proxy path (upstream) used to match incoming requests (optional).
	RewriteURL    string // RewriteURL is the URL to rewrite the incoming request to (downstream) (optional).
	Redirect      string // Redirect is the URL to redirect the request to (optional).
	SkipTLSVerify bool   // SkipTLSVerify determines whether to skip TLS certificate verification for backend connections (optional).
}

RouteConfig holds configuration settings for routing requests through the proxy.

type ServerPool

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

ServerPool manages a pool of backend servers, handling load balancing and connection management.

func NewServerPool

func NewServerPool(svc *config.Service, logger *zap.Logger) *ServerPool

func (*ServerPool) AddBackend

func (s *ServerPool) AddBackend(
	cfg config.BackendConfig,
	rc RouteConfig,
	hcCfg *config.HealthCheckConfig,
) error

AddBackend adds a new backend to the ServerPool with the specified configuration, route settings, and health check configuration. Parses the backend URL, creates a reverse proxy, initializes the backend, and updates the BackendSnapshot atomically.

func (*ServerPool) GetAlgorithm

func (s *ServerPool) GetAlgorithm() algorithm.Algorithm

GetAlgorithm returns the current load balancing algorithm used by the ServerPool.

func (*ServerPool) GetAllBackends added in v0.1.4

func (s *ServerPool) GetAllBackends() []*Backend

GetAllBackends returns a slice of all backends currently managed by the ServerPool.

func (*ServerPool) GetBackendByURL

func (s *ServerPool) GetBackendByURL(url string) *Backend

GetBackendByURL retrieves a backend from the pool based on its URL. Returns the Backend if found, otherwise returns nil.

func (*ServerPool) GetBackends

func (s *ServerPool) GetBackends() []*algorithm.Server

GetBackends returns a slice of all backend servers converted to algorithm.Server type for use in load balancing algorithms.

func (*ServerPool) GetConfig

func (s *ServerPool) GetConfig() PoolConfig

GetConfig retrieves the current configuration of the ServerPool, including the load balancing algorithm and maximum connections.

func (*ServerPool) GetCurrentIndex

func (s *ServerPool) GetCurrentIndex() uint64

GetCurrentIndex retrieves the current index used for round-robin load balancing.

func (*ServerPool) GetMaxConnections

func (s *ServerPool) GetMaxConnections() int32

GetMaxConnections retrieves the current maximum number of connections allowed per backend.

func (*ServerPool) GetNextPeer

func (s *ServerPool) GetNextPeer() *Backend

GetNextPeer selects the next available backend based on the current load balancing algorithm. It returns the selected backend or nil if no suitable backend is available.

func (*ServerPool) GetNextProxy

func (s *ServerPool) GetNextProxy(r *http.Request) *URLRewriteProxy

GetNextProxy retrieves the next available backend proxy based on the load balancing algorithm and increments its connection count. Returns the selected URLRewriteProxy or nil if no suitable backend is available.

func (*ServerPool) MarkBackendStatus

func (s *ServerPool) MarkBackendStatus(backendUrl *url.URL, alive bool)

MarkBackendStatus updates the alive status of a backend based on its URL. It is used by health checkers to mark backends as alive or dead.

func (*ServerPool) RemoveBackend

func (s *ServerPool) RemoveBackend(backendURL string) error

RemoveBackend removes an existing backend from the ServerPool based on its URL. It updates the BackendSnapshot atomically to exclude the specified backend. Returns an error if the backend URL is invalid or if the backend does not exist in the pool.

func (*ServerPool) SetAlgorithm

func (s *ServerPool) SetAlgorithm(algorithm algorithm.Algorithm)

SetAlgorithm sets a new load balancing algorithm for the ServerPool.

func (*ServerPool) SetCurrentIndex

func (s *ServerPool) SetCurrentIndex(idx uint64)

SetCurrentIndex sets the current index used for round-robin load balancing.

func (*ServerPool) SetMaxConnections

func (s *ServerPool) SetMaxConnections(maxConns int32)

SetMaxConnections sets a new maximum number of connections allowed per backend.

func (*ServerPool) UpdateBackends

func (s *ServerPool) UpdateBackends(configs []config.BackendConfig, serviceHealthCheck *config.HealthCheckConfig) error

UpdateBackends completely replaces the existing list of backends with a new set based on the provided configurations. It updates the load balancing algorithm and health check settings for each backend. Returns an error if any backend configuration is invalid.

func (*ServerPool) UpdateConfig

func (s *ServerPool) UpdateConfig(update PoolConfig)

UpdateConfig updates the ServerPool's configuration based on the provided PoolConfig. It allows changing the load balancing algorithm and the maximum number of connections dynamically.

type Transport

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

Transport wraps an http.RoundTripper to allow for custom transport configurations.

func NewTransport

func NewTransport(transport http.RoundTripper, skipTLSVerify bool) *Transport

NewTransport creates a new Transport instance with the provided RoundTripper. It configures the TLS settings based on the skipTLSVerify parameter. If skipTLSVerify is true, the Transport will not verify the server's TLS certificate.

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements the RoundTripper interface for the Transport type.

type URLRewriteProxy

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

URLRewriteProxy is a custom reverse proxy that handles URL rewriting and redirection based on RouteConfig.

func NewReverseProxy

func NewReverseProxy(
	target *url.URL,
	config RouteConfig,
	px *httputil.ReverseProxy,
	logger *zap.Logger,
	opts ...ProxyOption,
) *URLRewriteProxy

This sets up the reverse proxy with the specified target, route configurations, and applies any additional proxy options. The function also configures the reverse proxy's Director, ModifyResponse, Transport, ErrorHandler, and BufferPool.

func (*URLRewriteProxy) ServeHTTP

func (p *URLRewriteProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP handles incoming HTTP requests by determining whether to redirect or proxy the request. If a redirect is necessary based on the URLRewriter's logic, it performs the redirection. Otherwise, it forwards the request to the configured backend proxy.

type URLRewriter

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

URLRewriter is responsible for rewriting incoming request URLs based on predefined rules. It handles path prefix stripping, URL rewriting, and redirects to ensure that requests are correctly routed to the appropriate backend services.

func NewURLRewriter

func NewURLRewriter(config RewriteConfig, backendURL *url.URL) *URLRewriter

NewURLRewriter initializes and returns a new instance of URLRewriter based on the provided configuration. Determines whether the path prefix should be stripped and sets up the necessary rewrite and redirect rules.

Jump to

Keyboard shortcuts

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