fix radix get keys issue described at: #1328

Former-commit-id: beaf1f301ba8967fb7b56dc670818dedda324819
This commit is contained in:
Gerasimos (Makis) Maropoulos 2019-08-22 14:46:39 +03:00
parent 6f2de9ffdc
commit 9d09e8637b

View File

@ -1,11 +1,14 @@
package redis package redis
import ( import (
"bufio"
"errors"
"fmt" "fmt"
"math/rand" "math/rand"
"strconv" "strconv"
"github.com/mediocregopher/radix/v3" "github.com/mediocregopher/radix/v3"
"github.com/mediocregopher/radix/v3/resp/resp2"
) )
// RadixDriver the Redis service based on the radix go client, // RadixDriver the Redis service based on the radix go client,
@ -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), // 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. // look the `sessions/Database#OnUpdateExpiration` for example.
func (r *RadixDriver) UpdateTTLMany(prefix string, newSecondsLifeTime int64) error { func (r *RadixDriver) UpdateTTLMany(prefix string, newSecondsLifeTime int64) error {
keys, err := r.getKeys(prefix) keys, err := r.getKeys("0", prefix)
if err != nil { if err != nil {
return err return err
} }
@ -225,35 +228,54 @@ func (r *RadixDriver) GetAll() (interface{}, error) {
return redisVal, nil return redisVal, nil
} }
func (r *RadixDriver) getKeys(prefix string) ([]string, error) { type scanResult struct {
var keys []string cur string
// err := r.pool.Do(radix.Cmd(&keys, "MATCH", r.Config.Prefix+prefix+"*")) keys []string
// if err != nil { }
// return nil, err
// }
scanner := radix.NewScanner(r.pool, radix.ScanOpts{ func (s *scanResult) UnmarshalRESP(br *bufio.Reader) error {
Command: "SCAN", var ah resp2.ArrayHeader
Pattern: r.Config.Prefix + prefix + r.Config.Delim + "*", // get all of this session except its root sid. if err := ah.UnmarshalRESP(br); err != nil {
Count: 300000, 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):])
} }
if err := scanner.Close(); err != nil { var c resp2.BulkString
if err := c.UnmarshalRESP(br); err != nil {
return err
}
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 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 return keys, nil
} }
// GetKeys returns all redis keys using the "SCAN" with MATCH command. // GetKeys returns all redis keys using the "SCAN" with MATCH command.
// Read more at: https://redis.io/commands/scan#the-match-option. // Read more at: https://redis.io/commands/scan#the-match-option.
func (r *RadixDriver) GetKeys(prefix string) ([]string, error) { 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". // // GetBytes returns bytes representation of a value based on given "key".