Documentation ¶
Overview ¶
Package gopkg/redis is a componentized redis plugin.
It provides an easy way to configre and manage redis client.
Based on https://github.com/gomodule/redigo
Index ¶
- Variables
- func Bool(reply interface{}, err error) (bool, error)
- func ByteSlices(reply interface{}, err error) ([][]byte, error)
- func Bytes(reply interface{}, err error) ([]byte, error)
- func Float64(reply interface{}, err error) (float64, error)
- func Float64s(reply interface{}, err error) ([]float64, error)
- func Int(reply interface{}, err error) (int, error)
- func Int64(reply interface{}, err error) (int64, error)
- func Int64Map(result interface{}, err error) (map[string]int64, error)
- func Int64s(reply interface{}, err error) ([]int64, error)
- func IntMap(result interface{}, err error) (map[string]int, error)
- func Ints(reply interface{}, err error) ([]int, error)
- func IsErrNotOwnerOfLock(err error) bool
- func IsKeyNotExist(err error) bool
- func IsLockNotAcquired(err error) bool
- func IsLockNotExist(err error) bool
- func IsTimeout(err error) bool
- func Positions(result interface{}, err error) ([]*[2]float64, error)
- func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error)
- func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error
- func ScanStruct(src []interface{}, dest interface{}) error
- func SlowLogs(result interface{}, err error) ([]redigo.SlowLog, error)
- func String(reply interface{}, err error) (string, error)
- func StringMap(result interface{}, err error) (map[string]string, error)
- func Strings(reply interface{}, err error) ([]string, error)
- func Uint64(reply interface{}, err error) (uint64, error)
- func Uint64Map(result interface{}, err error) (map[string]uint64, error)
- func Uint64s(reply interface{}, err error) ([]uint64, error)
- func Values(reply interface{}, err error) ([]interface{}, error)
- type ClientOption
- func WithClientDSN(dsn string) ClientOption
- func WithClientIdleTimeout(idleTimeout int) ClientOption
- func WithClientMaxActive(maxActive int) ClientOption
- func WithClientMaxConnLifetime(maxConnLifetime int) ClientOption
- func WithClientMaxIdle(maxIdle int) ClientOption
- func WithClientTimeout(timeout int) ClientOption
- func WithClientWait(wait bool) ClientOption
- type ClientProxy
- type FetchOption
- func WithFetchCallback(callback func() (interface{}, error), expire time.Duration) FetchOption
- func WithFetchMarshal(marshal func(v interface{}) ([]byte, error)) FetchOption
- func WithFetchUnmarshal(unmarshal func(data []byte, dest interface{}) error) FetchOption
- func WithSingleflight(expire time.Duration) FetchOption
- type FetchOptions
- type FetcherProxy
- type LockOption
- type LockOptions
- type LockerProxy
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrTimeout ErrTimeout = errors.New("timeout") // ErrLockNotAcquired lock not acquired ErrLockNotAcquired = errors.New("lock not acquired") // ErrLockNotExist lock dose not exist ErrLockNotExist = errors.New("lock does not exist") // ErrNotOwnerOfLock not the owner of the key ErrNotOwnerOfLock = errors.New("not the owner of the lock") // ErrKeyNotExist key not exist ErrKeyNotExist = errors.New("key not exist") )
Functions ¶
func Bool ¶
Bool is a helper that converts a command reply to a boolean. If err is not equal to nil, then Bool returns false, err. Otherwise Bool converts the reply to boolean as follows:
Reply type Result integer value != 0, nil bulk string strconv.ParseBool(reply) nil false, ErrNil other false, error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func ByteSlices ¶
ByteSlices is a helper that converts an array command reply to a [][]byte. If err is not equal to nil, then ByteSlices returns nil, err. Nil array items are stay nil. ByteSlices returns an error if an array item is not a bulk string or nil.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Bytes ¶
Bytes is a helper that converts a command reply to a slice of bytes. If err is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts the reply to a slice of bytes as follows:
Reply type Result bulk string reply, nil simple string []byte(reply), nil nil nil, ErrNil other nil, error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Float64 ¶
Float64 is a helper that converts a command reply to 64 bit float. If err is not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts the reply to a float64 as follows:
Reply type Result bulk string parsed reply, nil nil 0, ErrNil other 0, error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Float64s ¶
Float64s is a helper that converts an array command reply to a []float64. If err is not equal to nil, then Float64s returns nil, err. Nil array items are converted to 0 in the output slice. Floats64 returns an error if an array item is not a bulk string or nil.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Int ¶
Int is a helper that converts a command reply to an integer. If err is not equal to nil, then Int returns 0, err. Otherwise, Int converts the reply to an int as follows:
Reply type Result integer int(reply), nil bulk string parsed reply, nil nil 0, ErrNil other 0, error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Int64 ¶
Int64 is a helper that converts a command reply to 64 bit integer. If err is not equal to nil, then Int64 returns 0, err. Otherwise, Int64 converts the reply to an int64 as follows:
Reply type Result integer reply, nil bulk string parsed reply, nil nil 0, ErrNil other 0, error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Int64Map ¶
Int64Map is a helper that converts an array of strings (alternating key, value) into a map[string]int64. The HGETALL commands return replies in this format. Requires an even number of values in result.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Int64s ¶
Int64s is a helper that converts an array command reply to a []int64. If err is not equal to nil, then Int64s returns nil, err. Nil array items are stay nil. Int64s returns an error if an array item is not a bulk string or nil.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func IntMap ¶
IntMap is a helper that converts an array of strings (alternating key, value) into a map[string]int. The HGETALL commands return replies in this format. Requires an even number of values in result.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Ints ¶
Ints is a helper that converts an array command reply to a []int. If err is not equal to nil, then Ints returns nil, err. Nil array items are stay nil. Ints returns an error if an array item is not a bulk string or nil.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func IsErrNotOwnerOfLock ¶
IsErrNotOwnerOfLock is not owner of lock
func IsLockNotAcquired ¶
IsLockNotAcquired is lock not acquired error
func Positions ¶
Positions is a helper that converts an array of positions (lat, long) into a [][2]float64. The GEOPOS command returns replies in this format.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Scan ¶
func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error)
Scan copies from src to the values pointed at by dest.
Scan uses RedisScan if available otherwise:
The values pointed at by dest must be an integer, float, boolean, string, []byte, interface{} or slices of these types. Scan uses the standard strconv package to convert bulk strings to numeric and boolean types.
If a dest value is nil, then the corresponding src value is skipped.
If a src element is nil, then the corresponding dest value is not modified.
To enable easy use of Scan in a loop, Scan returns the slice of src following the copied values.
See: https://github.com/gomodule/redigo/blob/master/redis/scan.go
func ScanSlice ¶
ScanSlice scans src to the slice pointed to by dest.
If the target is a slice of types which implement Scanner then the custom RedisScan method is used otherwise the following rules apply:
The elements in the dest slice must be integer, float, boolean, string, struct or pointer to struct values.
Struct fields must be integer, float, boolean or string values. All struct fields are used unless a subset is specified using fieldNames.
See: https://github.com/gomodule/redigo/blob/master/redis/scan.go
func ScanStruct ¶
func ScanStruct(src []interface{}, dest interface{}) error
ScanStruct scans alternating names and values from src to a struct. The HGETALL and CONFIG GET commands return replies in this format.
ScanStruct uses exported field names to match values in the response. Use 'redis' field tag to override the name:
Field int `redis:"myName"`
Fields with the tag redis:"-" are ignored.
Each field uses RedisScan if available otherwise: Integer, float, boolean, string and []byte fields are supported. Scan uses the standard strconv package to convert bulk string values to numeric and boolean types.
If a src element is nil, then the corresponding field is not modified.
See: https://github.com/gomodule/redigo/blob/master/redis/scan.go
func SlowLogs ¶
SlowLogs is a helper that parse the SLOWLOG GET command output and return the array of SlowLog
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func String ¶
String is a helper that converts a command reply to a string. If err is not equal to nil, then String returns "", err. Otherwise String converts the reply to a string as follows:
Reply type Result bulk string string(reply), nil simple string reply, nil nil "", ErrNil other "", error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func StringMap ¶
StringMap is a helper that converts an array of strings (alternating key, value) into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format. Requires an even number of values in result.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Strings ¶
Strings is a helper that converts an array command reply to a []string. If err is not equal to nil, then Strings returns nil, err. Nil array items are converted to "" in the output slice. Strings returns an error if an array item is not a bulk string or nil.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Uint64 ¶
Uint64 is a helper that converts a command reply to 64 bit unsigned integer. If err is not equal to nil, then Uint64 returns 0, err. Otherwise, Uint64 converts the reply to an uint64 as follows:
Reply type Result +integer reply, nil bulk string parsed reply, nil nil 0, ErrNil other 0, error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Uint64Map ¶
Uint64Map is a helper that converts an array of strings (alternating key, value) into a map[string]uint64. The HGETALL commands return replies in this format. Requires an even number of values in result.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Uint64s ¶
Uint64s is a helper that converts an array command reply to a []uint64. If err is not equal to nil, then Uint64s returns nil, err. Nil array items are stay nil. Uint64s returns an error if an array item is not a bulk string or nil.
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
func Values ¶
Values is a helper that converts an array command reply to a []interface{}. If err is not equal to nil, then Values returns nil, err. Otherwise, Values converts the reply as follows:
Reply type Result array reply, nil nil nil, ErrNil other nil, error
See: https://github.com/gomodule/redigo/blob/master/redis/reply.go
Types ¶
type ClientOption ¶
type ClientOption func(*serviceConfig)
ClientOption redis client proxy option
func WithClientIdleTimeout ¶
func WithClientIdleTimeout(idleTimeout int) ClientOption
WithClientIdleTimeout set idle timeout
Close connections after remaining idle for this duration. 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. Unit millisecond, default 180000
func WithClientMaxActive ¶
func WithClientMaxActive(maxActive int) ClientOption
WithClientMaxActive set max active
Maximum number of connections allocated by the pool at a given time. When zero, there is no limit on the number of connections in the pool. Default 0
func WithClientMaxConnLifetime ¶
func WithClientMaxConnLifetime(maxConnLifetime int) ClientOption
WithClientMaxConnLifetime set max conn lifetime
Close connections older than this duration. If the value is zero, then the pool does not close connections based on age. Unit millisecond, default 0
func WithClientMaxIdle ¶
func WithClientMaxIdle(maxIdle int) ClientOption
WithClientMaxIdle set max idle
Maximum number of connections in the idle connection pool. Default 2048
func WithClientTimeout ¶
func WithClientTimeout(timeout int) ClientOption
WithClientTimeout set timeout
Write, read and connect timeout Unit millisecond, default 1000
func WithClientWait ¶
func WithClientWait(wait bool) ClientOption
WithClientWait set wait
If Wait is true and the pool is at the MaxActive limit, then Get() waits for a connection to be returned to the pool before returning.
type ClientProxy ¶
type ClientProxy interface { // Do sends a command to server and returns the received reply. // min(ctx,DialReadTimeout()) will be used as the deadline. // The connection will be closed if DialReadTimeout() timeout or ctx timeout or ctx canceled when this function is running. // DialReadTimeout() timeout return err can be checked by strings.Contains(e.Error(), "io/timeout"). // ctx timeout return err context.DeadlineExceeded. // ctx canceled return err context.Canceled. Do(ctx context.Context, cmd string, args ...interface{}) (interface{}, error) // Conn gets a connection. The application must close the returned connection. // This method always returns a valid connection so that applications can defer // error handling to the first use of the connection. If there is an error // getting an underlying connection, then the connection Err, Do, Send, Flush and Receive methods return that error. Conn() redigo.Conn // Locker gets a distributed lock provider Locker() LockerProxy // Fetcher gets an object fetcher Fetcher() FetcherProxy }
ClientProxy Redis client proxy
Example ¶
package main import ( "context" "github.com/wwwangxc/gopkg/redis" ) func main() { // new client proxy cli := redis.NewClientProxy("client_name", redis.WithClientDSN("dsn"), // set dsn, default use database.client.dsn redis.WithClientMaxIdle(20), // set max idel. default 2048 redis.WithClientMaxActive(100), // set max active. default 0 redis.WithClientIdleTimeout(180000), // set idle timeout. unit millisecond, default 180000 redis.WithClientTimeout(1000), // set command timeout. unit millisecond, default 1000 redis.WithClientMaxConnLifetime(10000), // set max conn life time, default 0 redis.WithClientWait(true), // set wait ) // Do sends a command to server and returns the received reply. cli.Do(context.Background(), "GET", "foo") // Connection c := cli.Conn() defer c.Close() c.Send("SET", "foo", "bar") c.Send("GET", "foo") c.Flush() c.Receive() // reply from SET c.Receive() // reply from GET // Gets a distributed lock provider _ = cli.Locker() // Gets an object fetcher _ = cli.Fetcher() }
Output:
func NewClientProxy ¶
func NewClientProxy(name string, opts ...ClientOption) ClientProxy
NewClientProxy new redis client proxy
type FetchOption ¶
type FetchOption func(*FetchOptions)
FetchOption fetch option
func WithFetchCallback ¶
func WithFetchCallback(callback func() (interface{}, error), expire time.Duration) FetchOption
WithFetchCallback set fetch callback & expire option
The callback function will be called if the key does not exist. Will cache the callback results into the key and set timeout. Default do nothing.
func WithFetchMarshal ¶
func WithFetchMarshal(marshal func(v interface{}) ([]byte, error)) FetchOption
WithFetchMarshal set mashal function to fetcher
The marshal function will be called before cache. Default use json.Marshal.
func WithFetchUnmarshal ¶
func WithFetchUnmarshal(unmarshal func(data []byte, dest interface{}) error) FetchOption
WithFetchUnmarshal set unmarshal function to fetcher
Default use json.Unmarshal.
func WithSingleflight ¶ added in v0.1.2
func WithSingleflight(expire time.Duration) FetchOption
WithSingleflight use singleflight for fetcher
type FetchOptions ¶
type FetchOptions struct { Expire time.Duration ExpireSingleflight time.Duration Callback func() (interface{}, error) Marshal func(v interface{}) ([]byte, error) Unmarshal func(data []byte, dest interface{}) error }
FetchOptions fetch options
type FetcherProxy ¶
type FetcherProxy interface { // Fetch data and storing the result into the struct pointed at by dest. // // Use json decode Fetch(ctx context.Context, key string, dest interface{}, opts ...FetchOption) error }
FetcherProxy object fetcher
Example ¶
package main import ( "context" "encoding/json" "fmt" "time" "github.com/wwwangxc/gopkg/redis" ) func main() { obj := struct { FieldA string `json:"field_a"` FieldB int `json:"field_b"` }{} callback := func() (interface{}, error) { // load object return nil, nil } // new fetcher proxy f := redis.NewFetcherProxy("client_name", redis.WithClientDSN("dsn"), // set dsn, default use database.client.dsn redis.WithClientMaxIdle(20), // set max idel. default 2048 redis.WithClientMaxActive(100), // set max active. default 0 redis.WithClientIdleTimeout(180000), // set idle timeout. unit millisecond, default 180000 redis.WithClientTimeout(1000), // set command timeout. unit millisecond, default 1000 redis.WithClientMaxConnLifetime(10000), // set max conn life time, default 0 redis.WithClientWait(true), // set wait ) // fetch object err := f.Fetch(context.Background(), "fetcher_key", &obj, redis.WithFetchCallback(callback, 1000*time.Millisecond), // set callback method and cache result for 1000 millisecond redis.WithFetchUnmarshal(json.Unmarshal), // unmarshal by json redis.WithFetchMarshal(json.Marshal), // marshal by json redis.WithSingleflight(time.Second), // use singleflight for fetcher ) if err != nil { fmt.Printf("fetch fail. error: %v\n", err) return } }
Output:
func NewFetcherProxy ¶
func NewFetcherProxy(name string, opts ...ClientOption) FetcherProxy
NewFetcherProxy new object fetcher proxy
type LockOption ¶
type LockOption func(*LockOptions)
LockOption distributed lock option
func WithLockExpire ¶
func WithLockExpire(expire time.Duration) LockOption
WithLockExpire set lock expire
default 1000 millisecond
func WithLockHeartbeat ¶
func WithLockHeartbeat(heartbeat time.Duration) LockOption
WithLockHeartbeat set heartbeat
Heartbeat indicates the time interval for automatically renewal. Heartbeat = 0 means the lock will not automatically renewal when it expires. default 0
func WithLockRetry ¶
func WithLockRetry(retry time.Duration) LockOption
WithLockRetry set retry Retry indicates the time interval for retrying the acquire lock. Default 1000 millisecond
func WithLockUUID ¶
func WithLockUUID(uuid string) LockOption
WithLockUUID set uuid of the distributed lock
A non-null UUID indicates a reentrant lock.
type LockOptions ¶
type LockOptions struct { // UUID of the lock // A non-null UUID indicates a reentrant lock. UUID string // Expire of the lock // Default 1000 millisecond Expire time.Duration // Heartbeat indicates the time interval for automatically renewal. // Heartbeat = 0 means the lock will not automatically renewal when it expires. // Default 0 Heartbeat time.Duration // Retry indicates the time interval for retrying the acquire lock. // Default 1000 millisecond Retry time.Duration }
LockOptions distributed lock options
type LockerProxy ¶
type LockerProxy interface { // LockAndCall try get lock first and call f() when lock acquired. Unlock will be performed // regardless of whether the f reports an error or not. // // Will block the current goroutine when lock not acquired // Will reentrant lock when UUID option not empty. // If Heartbeat option not empty and not a reentrant lock, will automatically // renewal until unlocked. LockAndCall(ctx context.Context, key string, f func() error, opts ...LockOption) error // TryLock try get lock, if lock acquired will return lock uuid. // // Not block the current goroutine. // Return ErrLockNotAcquired when lock not acquired. // Will reentrant lock when UUID option not empty. // If Heartbeat option not empty and not a reentrant lock, will automatically // renewal until unlocked. TryLock(ctx context.Context, key string, opts ...LockOption) (uuid string, err error) // Lock try get lock until the context canceled or the lock acquired // // Will block the current goroutine. // Will reentrant lock when UUID option not empty. // If Heartbeat option not empty and not a reentrant lock, will automatically // renewal until unlocked. Lock(ctx context.Context, key string, opts ...LockOption) (uuid string, err error) // Unlock // // Return ErrLockNotExist if the key does not exist. // Return ErrNotOwnerOfKey if the uuid invalid. // Support reentrant unlock. Unlock(ctx context.Context, key, uuid string) error }
LockerProxy distributed lock provider
Example ¶
package main import ( "context" "fmt" "time" "github.com/wwwangxc/gopkg/redis" ) func main() { // new locker proxy l := redis.NewLockerProxy("client_name", redis.WithClientDSN("dsn"), // set dsn, default use database.client.dsn redis.WithClientMaxIdle(20), // set max idel. default 2048 redis.WithClientMaxActive(100), // set max active. default 0 redis.WithClientIdleTimeout(180000), // set idle timeout. unit millisecond, default 180000 redis.WithClientTimeout(1000), // set command timeout. unit millisecond, default 1000 redis.WithClientMaxConnLifetime(10000), // set max conn life time, default 0 redis.WithClientWait(true), // set wait ) // try lock // not block the current goroutine. // return uuid when the lock is acquired // return error when lock fail or lock not acquired // support reentrant unlock // support automatically renewal uuid, err := l.TryLock(context.Background(), "locker_key", redis.WithLockExpire(1000*time.Millisecond), redis.WithLockHeartbeat(500*time.Millisecond)) if err != nil { // return ErrLockNotAcquired when lock not acquired if redis.IsLockNotAcquired(err) { fmt.Printf("lock not acquired\n") return } fmt.Printf("try lock fail. error: %v\n", err) return } defer func() { // return ErrLockNotExist if the key does not exist // return ErrNotOwnerOfKey if the uuid invalid // support reentrant unlock if err := l.Unlock(context.Background(), "locker_key", uuid); err != nil { fmt.Printf("unlock fail. error: %v\n", err) } }() // reentrant lock when uuid not empty // will block the current goroutine until lock is acquired when not reentrant lock _, err = l.Lock(context.Background(), "locker_key", redis.WithLockUUID(uuid), redis.WithLockExpire(1000*time.Millisecond), redis.WithLockHeartbeat(500*time.Millisecond)) if err != nil { fmt.Printf("lock fail. error: %v\n", err) return } f := func() error { // do something... return nil } // try get lock first and call f() when lock acquired. Unlock will be performed // regardless of whether the f reports an error or not. if err := l.LockAndCall(context.Background(), "locker_key", f); err != nil { fmt.Printf("lock and call fail. error: %v\n", err) return } }
Output:
func NewLockerProxy ¶
func NewLockerProxy(name string, opts ...ClientOption) LockerProxy
NewLockerProxy new locker proxy