redisutil

package
v0.34.1 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2025 License: Unlicense Imports: 15 Imported by: 0

Documentation

Overview

Package redisutil contains common utilities for working with Redis.

Integration testing

To test with a real Redis database, call the tests with the environment variable TEST_REDIS_PORT set to the port of your database.

The tests use the database at index 15, which is chosen because it's the largest database index on most instances. The instance should also have the master role.

NOTE: The database is flushed between tests, so make sure that that database is not used for storing important data.

Index

Examples

Constants

View Source
const (
	LogPrefixValuePool        = "redis_pool"
	LogPrefixValueRoleChecker = "redis_role_checker"
)

Prefix values for the loggers of entities initialized by NewPoolFromEnvironment.

View Source
const (
	CmdDEL      = "DEL"
	CmdFCALL    = "FCALL"
	CmdFLUSHDB  = "FLUSHDB"
	CmdFUNCTION = "FUNCTION"
	CmdGET      = "GET"
	CmdPTTL     = "PTTL"
	CmdROLE     = "ROLE"
	CmdSET      = "SET"
)

Redis commands, parameters, and other constants.

View Source
const (
	ParamASYNC   = "ASYNC"
	ParamEX      = "EX"
	ParamLOAD    = "LOAD"
	ParamNX      = "NX"
	ParamPX      = "PX"
	ParamREPLACE = "REPLACE"
	ParamSYNC    = "SYNC"
)

Parameter constants.

View Source
const (
	RoleStringMaster   = "master"
	RoleStringSentinel = "sentinel"
	RoleStringSlave    = "slave"

	RoleMaster   Role = RoleStringMaster
	RoleSentinel Role = RoleStringSentinel
	RoleSlave    Role = RoleStringSlave
)

Valid Redis roles and their string representations.

View Source
const DefaultPort = 6379

DefaultPort is the default Redis port

View Source
const (
	// ErrStrFunctionNotFound is an error message returned by Redis on
	// [CmdFCALL] if the requested function is not found.
	ErrStrFunctionNotFound = "ERR Function not found"
)

Error string constants.

View Source
const (
	// MinTTL is the minimum TTL that can be set when setting any TTL.
	MinTTL = 1 * time.Millisecond
)

Redis-related limits.

View Source
const (
	RespOK = "OK"
)

Response constants.

Variables

This section is empty.

Functions

This section is empty.

Types

type ConnectionTester

type ConnectionTester interface {
	// TestConnection returns an error if c is not healthy.  lastUsed is the
	// time when the connection was returned to the pool.  c must not be nil.
	TestConnection(ctx context.Context, c redis.Conn, lastUsed time.Time) (err error)
}

ConnectionTester checks the health of an idle connection before the connection is used again by the application.

type DefaultDialer

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

DefaultDialer is the default implementation of the Dialer interface.

func NewDefaultDialer

func NewDefaultDialer(c *DefaultDialerConfig) (d *DefaultDialer, err error)

NewDefaultDialer returns a properly initialized default dialer. c should not be nil and should be valid.

func (*DefaultDialer) DialContext

func (d *DefaultDialer) DialContext(ctx context.Context) (conn redis.Conn, err error)

DialContext implements the Dialer interface for *DefaultDialer.

type DefaultDialerConfig

type DefaultDialerConfig struct {
	// Addr is the address of the Redis server.  It must not be nil and must be
	// valid.
	Addr *netutil.HostPort

	// Resolver is used to resolve the hostname.  If nil, a default pure-Go
	// [net.Resolver] is used.
	//
	// TODO(a.garipov):  Add the [netutil.Resolver] interface?
	Resolver *net.Resolver

	// Network is the network to dial.  If empty, "ip" is used.  If not empty,
	// must be one of:
	//   - "ip"
	//   - "ip4"
	//   - "ip6"
	Network string

	// DBIndex is the index of Redis database to use.  Zero is the default
	// index.
	DBIndex uint8
}

DefaultDialerConfig is the configuration structure for a DefaultDialer.

type DefaultPool

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

DefaultPool is a wrapper around redis.DefaultPool with metrics and additional options.

func NewDefaultPool

func NewDefaultPool(c *DefaultPoolConfig) (p *DefaultPool, err error)

NewDefaultPool returns a new properly initialized *DefaultPool. c should not be nil and should be valid.

func NewPoolFromEnvironment added in v0.32.12

func NewPoolFromEnvironment(
	ctx context.Context,
	baseLogger *slog.Logger,
	mtrc PoolMetrics,
) (p *DefaultPool, err error)

NewPoolFromEnvironment creates a new pool based on the environment. If baseLogger is nil, slog.Default is used. If mtrc is nil, EmptyPoolMetrics is used.

See Environment and its fields for more information about the environment variables that this function uses.

TODO(a.garipov): Find ways of testing.

func (*DefaultPool) Close

func (p *DefaultPool) Close() (err error)

Close implements the Pool interface for *DefaultPool.

func (*DefaultPool) Get

func (p *DefaultPool) Get(ctx context.Context) (c redis.Conn, err error)

Get implements the Pool interface for *DefaultPool. It returns a connection from the pool and also updates the pool metrics.

type DefaultPoolConfig

type DefaultPoolConfig struct {
	// Logger is used to log the operation of the Redis pool.  If nil,
	// [slog.Default] is used.
	Logger *slog.Logger

	// ConnectionTester checks the health of an idle connection before the
	// connection is used again.  If nil, no checks are performed.
	ConnectionTester ConnectionTester

	// Dialer is used to create and configure connections.  It should not be
	// nil.
	Dialer Dialer

	// Metrics is used for the collection of the Redis pool statistics.  If nil,
	// [EmptyPoolMetrics] is used.
	Metrics PoolMetrics

	// IdleTimeout is the time after remaining, idle connection will be closed.
	// If the value is zero, then idle connections are not closed.  Applications
	// should set the timeout to a value less than the server's timeout.
	// IdleTimeout should not be negative.
	IdleTimeout time.Duration

	// MaxConnLifetime is the total duration of any connection's lifetime.  If
	// the value is zero then the pool does not close connections based on age.
	// MaxConnLifetime should not be negative.
	MaxConnLifetime time.Duration

	// MaxActive is the maximum number of connections allocated by the Redis
	// connection-pool at a given time.  When zero, there is no limit on the
	// number of connections in the pool.  MaxActive should not be negative.
	MaxActive int

	// MaxIdle is the maximum number of idle connections in the pool.  When
	// zero, there is no limit.  MaxIdle should not be negative.
	MaxIdle int

	// Wait, if true, makes the pool wait for a connection once the
	// [DefaultPoolConfig.MaxActive] limit is reached.
	Wait bool
}

DefaultPoolConfig is the configuration for the default Redis pool.

type Dialer

type Dialer interface {
	// DialContext creates and configures a connection with the given context.
	// c must not be in a special state (subscribed to pubsub channel,
	// transaction started, etc.).
	//
	// See [redis.Pool.DialContext].
	DialContext(ctx context.Context) (c redis.Conn, err error)
}

Dialer is the interface for dialing Redis connections.

type EmptyPoolMetrics

type EmptyPoolMetrics struct{}

EmptyPoolMetrics is the implementation of the PoolMetrics interface that does nothing.

func (EmptyPoolMetrics) Update

Update implements the PoolMetrics interface for EmptyPoolMetrics.

type Environment added in v0.32.12

type Environment struct {
	// Host is the value of the REDIS_HOST environment variable, which is used
	// together with Port to create the address to connect to.  The default
	// value is "localhost".
	Host string `env:"REDIS_HOST" envDefault:"localhost"`

	// Network is the value of the REDIS_NETWORK environment variable, which
	// shows what kind of IP protocol version to use:
	//   - "ip" means both;
	//   - "ip4" means IPv4 only;
	//   - "ip6" means IPv6 only.
	// All other values are invalid.  The default value is "ip4".
	Network string `env:"REDIS_NETWORK" envDefault:"ip4"`

	// IdleTimeout is the value of the REDIS_IDLE_TIMEOUT environment variable,
	// which is used to set the idle timeout for connections in a pool; see
	// [DefaultPoolConfig.IdleTimeout].  The duration should be in the
	// [time.Duration] format.  The default value is "5m".
	IdleTimeout timeutil.Duration `env:"REDIS_IDLE_TIMEOUT" envDefault:"5m"`

	// MaxConnLifetime is the value of the REDIS_MAX_CONN_LIFETIME environment
	// variable, which is used to set the maximum total duration of connections
	// in a pool; see [DefaultPoolConfig.MaxConnLifetime].  The duration should
	// be in the [time.Duration] format.  The default value is "0s", which means
	// that the lifetime is not limited.
	MaxConnLifetime timeutil.Duration `env:"REDIS_MAX_CONN_LIFETIME" envDefault:"0s"`

	// MaxActive is the value of the REDIS_MAX_ACTIVE environment variable,
	// which is used to set the maximum number of connections in a pool; see
	// [DefaultPoolConfig.MaxActive].  The default value is 100.
	MaxActive int `env:"REDIS_MAX_ACTIVE" envDefault:"100"`

	// MaxIdle is the value of the REDIS_MAX_IDLE environment variable, which is
	// used to set the maximum number of idle connections in a pool; see
	// [DefaultPoolConfig.MaxIdle].  The default value is 100.
	MaxIdle int `env:"REDIS_MAX_IDLE" envDefault:"100"`

	// Port is the value of the REDIS_PORT environment variable, which is used
	// together with HOST to create the address to connect to.  The default
	// value is 6379.
	Port uint16 `env:"REDIS_PORT" envDefault:"6379"`

	// DBIndex is the value of the REDIS_DB environment variable, denoting the
	// index of Redis database to use.  The default value is 0.
	DBIndex uint8 `env:"REDIS_DB" envDefault:"0"`

	// Wait is the value of the REDIS_WAIT environment variable, which selects
	// if the pool must wait for a connection once the MaxActive limit is
	// reached; see [DefaultPoolConfig.Wait].  The default is to wait.
	Wait bool `env:"REDIS_WAIT" envDefault:"1"`
}

Environment represents the Redis pool configuration that is kept in the environment.

type Pool

type Pool interface {
	// Get returns a connection from the pool.  If the context expires before
	// the connection is complete, an error must be returned; any expiration on
	// the context must not affect the returned connection.  If the function
	// completes without error, then the application should close the returned
	// connection.
	Get(ctx context.Context) (c redis.Conn, err error)

	// Close must release the resources used by the pool.
	Close() (err error)
}

Pool is a pool of Redis connections.

type PoolMetrics

type PoolMetrics interface {
	// Update updates the total number of active connections and increments the
	// total number of errors if necessary.
	Update(ctx context.Context, s redis.PoolStats, err error)
}

PoolMetrics is an interface that is used for the collection of the Redis pool statistics.

type Role

type Role string

Role is a valid Redis role.

func NewRole

func NewRole(s string) (r Role, err error)

NewRole converts s into a role.

Example
package main

import (
	"fmt"

	"github.com/AdguardTeam/golibs/redisutil"
)

func main() {
	r, err := redisutil.NewRole("master")
	fmt.Printf("%q %v\n", r, err)

	r, err = redisutil.NewRole("bad role")
	fmt.Printf("%q %v\n", r, err)

}
Output:

"master" <nil>
"" bad enum value: "bad role"

func (Role) Validate

func (r Role) Validate() (err error)

Validate implements the validate.Interface interface for Role.

type RoleChecker

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

RoleChecker is a ConnectionTester that simplifies checking connection roles in a DefaultPool.

func NewRoleChecker

func NewRoleChecker(c *RoleCheckerConfig) (rc *RoleChecker, err error)

NewRoleChecker returns a new properly initialized *RoleChecker. If c is nil, the defaults are used.

func (*RoleChecker) TestConnection

func (c *RoleChecker) TestConnection(
	ctx context.Context,
	conn redis.Conn,
	lastUsed time.Time,
) (err error)

TestConnection implements the ConnectionTester interface for *RoleChecker.

type RoleCheckerConfig

type RoleCheckerConfig struct {
	// Logger is used to log the operation of the checker.  If nil,
	// [slog.Default] is used.
	Logger *slog.Logger

	// Role is the required role.  If empty, [RoleMaster] is used; otherwise it
	// must be a valid Role.
	Role Role
}

RoleCheckerConfig is the configuration structure for a RoleChecker.

Jump to

Keyboard shortcuts

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