redisx

package module
v0.9.0 Latest Latest
Warning

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

Go to latest
Published: Dec 17, 2024 License: MIT Imports: 10 Imported by: 0

README

redisx Build Status codecov Go Report Card

redisx is a library of Go utilities built on the redigo redis client library.

NewPool

Simplifies creating a new Redis connection pool, with optional auth, and tests that the connection works:

rp, err := redisx.NewPool(
    "redis://username:password@localhost:6379/15", 
    redisx.WithMaxActive(10), 
    redisx.WithMaxIdle(3), 
    redisx.WithIdleTimeout(time.Minute)
)

IntervalSet

Creating very large numbers of Redis keys can hurt performance, but putting them all in a single set requires that they all have the same expiration. IntervalSet is a way to have multiple sets based on time intervals, accessible like a single set. You trade accuracy of expiry times for a significantly reduced key space. For example using 2 intervals of 24 hours:

set := NewIntervalSet("foos", time.Hour*24, 2)
set.Add(rc, "A")  // time is 2021-12-02T09:00
...
set.Add(rc, "B")  // time is 2021-12-03T10:00
set.Add(rc, "C")  // time is 2021-12-03T11:00

Creates 2 Redis sets like:

foos:2021-12-02 => {"A"}       // expires at 2021-12-04T09:00
foos:2021-12-03 => {"B", "C"}  // expires at 2021-12-05T11:00

But can be accessed like a single set:

set.IsMember(rc, "A")   // true
set.IsMember(rc, "B")   // true
set.IsMember(rc, "D")   // false

IntervalHash

Same idea as IntervalSet but for hashes, and works well for caching values. For example using 2 intervals of 1 hour:

hash := NewIntervalHash("foos", time.Hour, 2)
hash.Set(rc, "A", "1")  // time is 2021-12-02T09:10
...
hash.Set(rc, "B", "2")  // time is 2021-12-02T10:15
hash.Set(rc, "C", "3")  // time is 2021-12-02T10:20

Creates 2 Redis hashes like:

foos:2021-12-02T09:00 => {"A": "1"}            // expires at 2021-12-02T11:10
foos:2021-12-02T10:00 => {"B": "2", "C": "3"}  // expires at 2021-12-02T12:20

But can be accessed like a single hash:

hash.Get(rc, "A")   // "1"
hash.Get(rc, "B")   // "2"
hash.Get(rc, "D")   // ""

IntervalSeries

When getting a value from an IntervalHash you're getting the newest value by looking back through the intervals. IntervalSeries however lets you get an accumulated value from each interval.

For example using 3 intervals of 1 hour:

series := NewIntervalSeries("foos", time.Hour, 3)
series.Record(rc, "A", 1)  // time is 2021-12-02T09:10
series.Record(rc, "A", 2)  // time is 2021-12-02T09:15
...
series.Record(rc, "A", 3)  // time is 2021-12-02T10:15
series.Record(rc, "A", 4)  // time is 2021-12-02T10:20
...
series.Record(rc, "A", 5)  // time is 2021-12-02T11:25
series.Record(rc, "B", 1)  // time is 2021-12-02T11:30

Creates 3 Redis hashes like:

foos:2021-12-02T09:00 => {"A": "3"}            // expires at 2021-12-02T12:15
foos:2021-12-02T10:00 => {"A": "7"}            // expires at 2021-12-02T13:20
foos:2021-12-02T11:00 => {"A": "5", "B": "1"}  // expires at 2021-12-02T14:30

But lets us retrieve values across intervals:

series.Get(rc, "A")   // [5, 7, 3]
series.Get(rc, "B")   // [1, 0, 0]
series.Get(rc, "C")   // [0, 0, 0]

CappedZSet

The CappedZSet type is based on a sorted set but enforces a cap on size, by only retaining the highest ranked members.

cset := NewCappedZSet("foos", 3, time.Hour*24)
cset.Add(rc, "A", 1) 
cset.Add(rc, "C", 3) 
cset.Add(rc, "D", 4)
cset.Add(rc, "B", 2) 
cset.Add(rc, "E", 5) 
cset.Members(rc)      // ["C", "D", "E"] / [3, 4, 5]

Testing Asserts

The assertredis package contains several asserts useful for testing the state of a Redis database.

rp := assertredis.TestDB()
rc := rp.Get()
defer rc.Close()

assertredis.Keys(t, rc, "*", []string{"foo", "bar"})
assertredis.Exists(t, rc, "foo")
assertredis.NotExists(t, rc, "bar")
assertredis.Get(t, rc, "foo", "123")
assertredis.SCard(t, rc, "foo_set", 2)
assertredis.SMembers(t, rc, "foo_set", []string{"123", "234"})

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewPool added in v0.6.0

func NewPool(redisURL string, options ...func(*redis.Pool)) (*redis.Pool, error)

NewPool creates a new pool with the given options

func RandomBase64

func RandomBase64(n int) string

RandomBase64 creates a random string of the length passed in

func StringsWithScores

func StringsWithScores(reply any, err error) ([]string, []float64, error)

StringsWithScores parses an array reply which is alternating pairs of strings and scores (floats)

func WithIdleTimeout added in v0.6.0

func WithIdleTimeout(v time.Duration) func(*redis.Pool)

WithIdleTimeout configures how long to wait before reaping a connection

func WithMaxActive added in v0.6.0

func WithMaxActive(v int) func(*redis.Pool)

WithMaxActive configures maximum number of concurrent connections to allow

func WithMaxIdle added in v0.6.0

func WithMaxIdle(v int) func(*redis.Pool)

WithMaxIdle configures the maximum number of idle connections to keep

Types

type CappedZSet

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

CappedZSet is a sorted set but enforces a cap on size

func NewCappedZSet

func NewCappedZSet(key string, cap int, expire time.Duration) *CappedZSet

NewCappedZSet creates a new capped sorted set

func (*CappedZSet) Add

func (z *CappedZSet) Add(rc redis.Conn, member string, score float64) error

Add adds an element to the set, if its score puts in the top `cap` members

func (*CappedZSet) Card

func (z *CappedZSet) Card(rc redis.Conn) (int, error)

Card returns the cardinality of the set

func (*CappedZSet) Members

func (z *CappedZSet) Members(rc redis.Conn) ([]string, []float64, error)

Members returns all members of the set, ordered by ascending rank

type IntervalHash

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

IntervalHash operates like a hash map but with expiring intervals

func NewIntervalHash

func NewIntervalHash(keyBase string, interval time.Duration, size int) *IntervalHash

NewIntervalHash creates a new empty interval hash

func (*IntervalHash) Clear added in v0.5.0

func (h *IntervalHash) Clear(rc redis.Conn) error

Clear removes all fields

func (*IntervalHash) Del added in v0.5.0

func (h *IntervalHash) Del(rc redis.Conn, fields ...string) error

Del removes the given fields

func (*IntervalHash) Get

func (h *IntervalHash) Get(rc redis.Conn, field string) (string, error)

Get returns the value of the given field

func (*IntervalHash) MGet added in v0.5.0

func (h *IntervalHash) MGet(rc redis.Conn, fields ...string) ([]string, error)

MGet returns the values of the given fields

func (*IntervalHash) Set

func (h *IntervalHash) Set(rc redis.Conn, field, value string) error

Set sets the value of the given field

type IntervalSeries

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

IntervalSeries returns all values from interval based hashes.

func NewIntervalSeries

func NewIntervalSeries(keyBase string, interval time.Duration, size int) *IntervalSeries

NewIntervalSeries creates a new empty series

func (*IntervalSeries) Get

func (s *IntervalSeries) Get(rc redis.Conn, field string) ([]int64, error)

Get gets the values of field in all intervals

func (*IntervalSeries) Record

func (s *IntervalSeries) Record(rc redis.Conn, field string, value int64) error

Record increments the value of field by value in the current interval

func (*IntervalSeries) Total

func (s *IntervalSeries) Total(rc redis.Conn, field string) (int64, error)

Total gets the total value of field across all intervals

type IntervalSet

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

IntervalSet operates like a set but with expiring intervals

func NewIntervalSet

func NewIntervalSet(keyBase string, interval time.Duration, size int) *IntervalSet

NewIntervalSet creates a new empty interval set

func (*IntervalSet) Add

func (s *IntervalSet) Add(rc redis.Conn, member string) error

Add adds the given value

func (*IntervalSet) Clear added in v0.5.0

func (s *IntervalSet) Clear(rc redis.Conn) error

Clear removes all values

func (*IntervalSet) IsMember added in v0.5.0

func (s *IntervalSet) IsMember(rc redis.Conn, member string) (bool, error)

IsMember returns whether we contain the given value

func (*IntervalSet) Rem added in v0.5.0

func (s *IntervalSet) Rem(rc redis.Conn, members ...string) error

Rem removes the given values

type Locker

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

Locker is a lock implementation where grabbing returns a lock value and that value must be used to release or extend the lock.

func NewLocker

func NewLocker(key string, expiration time.Duration) *Locker

NewLocker creates a new locker using the given key and expiration

func (*Locker) Extend

func (l *Locker) Extend(rp *redis.Pool, value string, expiration time.Duration) error

Extend extends our lock expiration by the passed in number of seconds provided the lock value is correct

func (*Locker) Grab

func (l *Locker) Grab(rp *redis.Pool, retry time.Duration) (string, error)

Grab tries to grab this lock in an atomic operation. It returns the lock value if successful. It will retry every second until the retry period has ended, returning empty string if not acquired in that time.

func (*Locker) Release

func (l *Locker) Release(rp *redis.Pool, value string) error

Release releases this lock if the given lock value is correct (i.e we own this lock). It is not an error to release a lock that is no longer present.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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