Skip to content

Commit

Permalink
fix radix get keys issue described at: #1328
Browse files Browse the repository at this point in the history
  • Loading branch information
kataras committed Aug 22, 2019
1 parent 198c789 commit bcd6c63
Showing 1 changed file with 39 additions and 17 deletions.
56 changes: 39 additions & 17 deletions sessions/sessiondb/redis/driver_radix.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package redis

import (
"bufio"
"errors"
"fmt"
"math/rand"
"strconv"

"github.com/mediocregopher/radix/v3"
"github.com/mediocregopher/radix/v3/resp/resp2"
)

// RadixDriver the Redis service based on the radix go client,
Expand Down Expand Up @@ -195,7 +198,7 @@ func (r *RadixDriver) UpdateTTL(key string, newSecondsLifeTime int64) error {
// it is a bit faster operation if you need to update all sessions keys (although it can be even faster if we used hash but this will limit other features),
// look the `sessions/Database#OnUpdateExpiration` for example.
func (r *RadixDriver) UpdateTTLMany(prefix string, newSecondsLifeTime int64) error {
keys, err := r.getKeys(prefix)
keys, err := r.getKeys("0", prefix)
if err != nil {
return err
}
Expand Down Expand Up @@ -225,35 +228,54 @@ func (r *RadixDriver) GetAll() (interface{}, error) {
return redisVal, nil
}

func (r *RadixDriver) getKeys(prefix string) ([]string, error) {
var keys []string
// err := r.pool.Do(radix.Cmd(&keys, "MATCH", r.Config.Prefix+prefix+"*"))
// if err != nil {
// return nil, err
// }
type scanResult struct {
cur string
keys []string
}

scanner := radix.NewScanner(r.pool, radix.ScanOpts{
Command: "SCAN",
Pattern: r.Config.Prefix + prefix + r.Config.Delim + "*", // get all of this session except its root sid.
Count: 300000,
})
func (s *scanResult) UnmarshalRESP(br *bufio.Reader) error {
var ah resp2.ArrayHeader
if err := ah.UnmarshalRESP(br); err != nil {
return err
} else if ah.N != 2 {
return errors.New("not enough parts returned")
}

var key string
for scanner.Next(&key) {
keys = append(keys, key[len(r.Config.Prefix):])
var c resp2.BulkString
if err := c.UnmarshalRESP(br); err != nil {
return err
}

if err := scanner.Close(); err != nil {
s.cur = c.S
s.keys = s.keys[:0]

return (resp2.Any{I: &s.keys}).UnmarshalRESP(br)
}

func (r *RadixDriver) getKeys(cursor, prefix string) ([]string, error) {
var res scanResult
err := r.pool.Do(radix.Cmd(&res, "SCAN", cursor, "MATCH", r.Config.Prefix+prefix+"*", "COUNT", "300000"))
if err != nil {
return nil, err
}

keys := res.keys[0:]
if res.cur != "0" {
moreKeys, err := r.getKeys(res.cur, prefix)
if err != nil {
return nil, err
}

keys = append(keys, moreKeys...)
}

return keys, nil
}

// GetKeys returns all redis keys using the "SCAN" with MATCH command.
// Read more at: https://redis.io/commands/scan#the-match-option.
func (r *RadixDriver) GetKeys(prefix string) ([]string, error) {
return r.getKeys(prefix)
return r.getKeys("0", prefix)
}

// // GetBytes returns bytes representation of a value based on given "key".
Expand Down

0 comments on commit bcd6c63

Please sign in to comment.