Skip to content

Commit

Permalink
feat: redis v9 support (#47)
Browse files Browse the repository at this point in the history
* feat: redis v7 support

This PR upgrades the upstream redis library to v9 which introduces support for Redis v7.

There have been a number of changes to the upstream configuration struct highlighted below:
* Renamed: `MaxConnAge` -> `ConnMaxLifetime`
* Renamed: `IdleTimeout` -> `ConnMaxIdleTime`
* Renamed: `SlaveOnly` -> `ReplicaOnly`
* Removed: `IdleCheckFrequency` connection reaper in favor of `MaxIdleConnections`

The renamed items have been remapped to the respective configuration upstream without any name changes.
If you prefer that we match the options I can adjust that, just let me know.

* refactor: build tags locking v9 redis library to go1.19+

* refactor: factorize code and include old fields as deprecated

* fix: typo in deprecation text

* fix: undefined errors
  • Loading branch information
nightah authored May 5, 2023
1 parent fc416db commit 0377885
Show file tree
Hide file tree
Showing 7 changed files with 604 additions and 169 deletions.
9 changes: 5 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ go 1.17
require (
github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746
github.com/go-redis/redis/v8 v8.11.5
github.com/go-sql-driver/mysql v1.7.0
github.com/lib/pq v1.10.7
github.com/go-sql-driver/mysql v1.7.1
github.com/lib/pq v1.10.9
github.com/mattn/go-sqlite3 v1.14.16
github.com/redis/go-redis/v9 v9.0.4
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee
github.com/tinylib/msgp v1.1.8
github.com/valyala/bytebufferpool v1.0.0
github.com/valyala/fasthttp v1.45.0
github.com/valyala/fasthttp v1.47.0
go.mongodb.org/mongo-driver v1.11.4
)

Expand All @@ -21,7 +22,7 @@ require (
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/go-cmp v0.5.5 // indirect
github.com/klauspost/compress v1.16.3 // indirect
github.com/klauspost/compress v1.16.5 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
Expand Down
21 changes: 14 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746 h1:wAIE/kN63Oig1DdOzN7O+k4AbFh2cCJoKMFXrwRJtzk=
github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/bsm/ginkgo/v2 v2.7.0 h1:ItPMPH90RbmZJt5GtkcNvIRuGEdwlBItdNVoyzaNQao=
github.com/bsm/ginkgo/v2 v2.7.0/go.mod h1:AiKlXPm7ItEHNc/2+OkrNG4E0ITzojb9/xWzvQ9XZ9w=
github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
Expand All @@ -18,8 +22,8 @@ github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
Expand All @@ -43,15 +47,16 @@ github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.16.3 h1:XuJt9zzcnaz6a16/OU53ZjWp/v7/42WcR5t2a0PcNQY=
github.com/klauspost/compress v1.16.3/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI=
github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe h1:iruDEfMl2E6fbMZ9s0scYfZQ84/6SPL6zC8ACM2oIL0=
Expand All @@ -76,6 +81,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.0.4 h1:FC82T+CHJ/Q/PdyLW++GeCO+Ol59Y4T7R4jbgjvktgc=
github.com/redis/go-redis/v9 v9.0.4/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee h1:8Iv5m6xEo1NR1AvpV+7XmhI4r39LGNzwUL4YpMuL5vk=
github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee/go.mod h1:qwtSXrKuJh/zsFQ12yEE89xfCrGKK63Rr7ctU/uCo4g=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand All @@ -88,8 +95,8 @@ github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.45.0 h1:zPkkzpIn8tdHZUrVa6PzYd0i5verqiPSkgTd3bSUcpA=
github.com/valyala/fasthttp v1.45.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
github.com/valyala/fasthttp v1.47.0 h1:y7moDoxYzMooFpT5aHgNgVOQDrS3qlkfiP9mDtGGK9c=
github.com/valyala/fasthttp v1.47.0/go.mod h1:k2zXd82h/7UZc3VOdJ2WaUqt1uZ/XpXAfE9i+HBC3lA=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
Expand Down
228 changes: 91 additions & 137 deletions providers/redis/provider.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//go:build go1.19
// +build go1.19

package redis

import (
"context"
"time"

"github.com/go-redis/redis/v8"
"github.com/valyala/bytebufferpool"
"github.com/redis/go-redis/v9"
)

var all = []byte("*")
Expand All @@ -20,26 +21,34 @@ func New(cfg Config) (*Provider, error) {
redis.SetLogger(cfg.Logger)
}

if cfg.MaxConnAge != 0 {
cfg.ConnMaxLifetime = cfg.MaxConnAge
}

if cfg.IdleTimeout != 0 {
cfg.ConnMaxIdleTime = cfg.IdleTimeout
}

db := redis.NewClient(&redis.Options{
Network: cfg.Network,
Addr: cfg.Addr,
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: cfg.MaxRetries,
MinRetryBackoff: cfg.MinRetryBackoff,
MaxRetryBackoff: cfg.MaxRetryBackoff,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
MaxConnAge: cfg.MaxConnAge,
PoolTimeout: cfg.PoolTimeout,
IdleTimeout: cfg.IdleTimeout,
IdleCheckFrequency: cfg.IdleCheckFrequency,
TLSConfig: cfg.TLSConfig,
Limiter: cfg.Limiter,
Network: cfg.Network,
Addr: cfg.Addr,
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: cfg.MaxRetries,
MinRetryBackoff: cfg.MinRetryBackoff,
MaxRetryBackoff: cfg.MaxRetryBackoff,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
MaxIdleConns: cfg.MaxIdleConns,
ConnMaxIdleTime: cfg.ConnMaxIdleTime,
ConnMaxLifetime: cfg.ConnMaxLifetime,
PoolTimeout: cfg.PoolTimeout,
TLSConfig: cfg.TLSConfig,
Limiter: cfg.Limiter,
})

if err := db.Ping(context.Background()).Err(); err != nil {
Expand All @@ -64,28 +73,36 @@ func NewFailover(cfg FailoverConfig) (*Provider, error) {
redis.SetLogger(cfg.Logger)
}

if cfg.MaxConnAge != 0 {
cfg.ConnMaxLifetime = cfg.MaxConnAge
}

if cfg.IdleTimeout != 0 {
cfg.ConnMaxIdleTime = cfg.IdleTimeout
}

db := redis.NewFailoverClient(&redis.FailoverOptions{
MasterName: cfg.MasterName,
SentinelAddrs: cfg.SentinelAddrs,
SentinelUsername: cfg.SentinelUsername,
SentinelPassword: cfg.SentinelPassword,
SlaveOnly: cfg.SlaveOnly,
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: cfg.MaxRetries,
MinRetryBackoff: cfg.MinRetryBackoff,
MaxRetryBackoff: cfg.MaxRetryBackoff,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
MaxConnAge: cfg.MaxConnAge,
PoolTimeout: cfg.PoolTimeout,
IdleTimeout: cfg.IdleTimeout,
IdleCheckFrequency: cfg.IdleCheckFrequency,
TLSConfig: cfg.TLSConfig,
MasterName: cfg.MasterName,
SentinelAddrs: cfg.SentinelAddrs,
SentinelUsername: cfg.SentinelUsername,
SentinelPassword: cfg.SentinelPassword,
ReplicaOnly: cfg.ReplicaOnly,
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: cfg.MaxRetries,
MinRetryBackoff: cfg.MinRetryBackoff,
MaxRetryBackoff: cfg.MaxRetryBackoff,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
MaxIdleConns: cfg.MaxIdleConns,
ConnMaxIdleTime: cfg.ConnMaxIdleTime,
ConnMaxLifetime: cfg.ConnMaxLifetime,
PoolTimeout: cfg.PoolTimeout,
TLSConfig: cfg.TLSConfig,
})

if err := db.Ping(context.Background()).Err(); err != nil {
Expand All @@ -110,30 +127,38 @@ func NewFailoverCluster(cfg FailoverConfig) (*Provider, error) {
redis.SetLogger(cfg.Logger)
}

if cfg.MaxConnAge != 0 {
cfg.ConnMaxLifetime = cfg.MaxConnAge
}

if cfg.IdleTimeout != 0 {
cfg.ConnMaxIdleTime = cfg.IdleTimeout
}

db := redis.NewFailoverClusterClient(&redis.FailoverOptions{
MasterName: cfg.MasterName,
SentinelAddrs: cfg.SentinelAddrs,
SentinelUsername: cfg.SentinelUsername,
SentinelPassword: cfg.SentinelPassword,
RouteByLatency: cfg.RouteByLatency,
RouteRandomly: cfg.RouteRandomly,
SlaveOnly: cfg.SlaveOnly,
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: cfg.MaxRetries,
MinRetryBackoff: cfg.MinRetryBackoff,
MaxRetryBackoff: cfg.MaxRetryBackoff,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
MaxConnAge: cfg.MaxConnAge,
PoolTimeout: cfg.PoolTimeout,
IdleTimeout: cfg.IdleTimeout,
IdleCheckFrequency: cfg.IdleCheckFrequency,
TLSConfig: cfg.TLSConfig,
MasterName: cfg.MasterName,
SentinelAddrs: cfg.SentinelAddrs,
SentinelUsername: cfg.SentinelUsername,
SentinelPassword: cfg.SentinelPassword,
RouteByLatency: cfg.RouteByLatency,
RouteRandomly: cfg.RouteRandomly,
ReplicaOnly: cfg.ReplicaOnly,
Username: cfg.Username,
Password: cfg.Password,
DB: cfg.DB,
MaxRetries: cfg.MaxRetries,
MinRetryBackoff: cfg.MinRetryBackoff,
MaxRetryBackoff: cfg.MaxRetryBackoff,
DialTimeout: cfg.DialTimeout,
ReadTimeout: cfg.ReadTimeout,
WriteTimeout: cfg.WriteTimeout,
PoolSize: cfg.PoolSize,
MinIdleConns: cfg.MinIdleConns,
MaxIdleConns: cfg.MaxIdleConns,
ConnMaxIdleTime: cfg.ConnMaxIdleTime,
ConnMaxLifetime: cfg.ConnMaxLifetime,
PoolTimeout: cfg.PoolTimeout,
TLSConfig: cfg.TLSConfig,
})

if err := db.Ping(context.Background()).Err(); err != nil {
Expand All @@ -148,19 +173,6 @@ func NewFailoverCluster(cfg FailoverConfig) (*Provider, error) {
return p, nil
}

func (p *Provider) getRedisSessionKey(sessionID []byte) string {
key := bytebufferpool.Get()
key.SetString(p.keyPrefix)
key.WriteString(":")
key.Write(sessionID)

keyStr := key.String()

bytebufferpool.Put(key)

return keyStr
}

// Get returns the data of the given session id
func (p *Provider) Get(id []byte) ([]byte, error) {
key := p.getRedisSessionKey(id)
Expand All @@ -173,61 +185,3 @@ func (p *Provider) Get(id []byte) ([]byte, error) {
return reply, nil

}

// Save saves the session data and expiration from the given session id
func (p *Provider) Save(id, data []byte, expiration time.Duration) error {
key := p.getRedisSessionKey(id)

return p.db.Set(context.Background(), key, data, expiration).Err()
}

// Regenerate updates the session id and expiration with the new session id
// of the the given current session id
func (p *Provider) Regenerate(id, newID []byte, expiration time.Duration) error {
key := p.getRedisSessionKey(id)
newKey := p.getRedisSessionKey(newID)

exists, err := p.db.Exists(context.Background(), key).Result()
if err != nil {
return err
}

if exists > 0 { // Exist
if err = p.db.Rename(context.Background(), key, newKey).Err(); err != nil {
return err
}

if err = p.db.Expire(context.Background(), newKey, expiration).Err(); err != nil {
return err
}
}

return nil
}

// Destroy destroys the session from the given id
func (p *Provider) Destroy(id []byte) error {
key := p.getRedisSessionKey(id)

return p.db.Del(context.Background(), key).Err()
}

// Count returns the total of stored sessions
func (p *Provider) Count() int {
reply, err := p.db.Keys(context.Background(), p.getRedisSessionKey(all)).Result()
if err != nil {
return 0
}

return len(reply)
}

// NeedGC indicates if the GC needs to be run
func (p *Provider) NeedGC() bool {
return false
}

// GC destroys the expired sessions
func (p *Provider) GC() error {
return nil
}
Loading

0 comments on commit 0377885

Please sign in to comment.