first commit
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
andrey1s
2021-04-26 17:13:36 +03:00
commit 7da0cd57ce
45 changed files with 3703 additions and 0 deletions

110
provider/redis/pool.go Normal file
View File

@@ -0,0 +1,110 @@
package redis
import (
"context"
"fmt"
"gitoa.ru/go-4devs/cache"
)
type Conn interface {
Do(commandName string, args ...interface{}) (reply interface{}, err error)
Send(commandName string, args ...interface{}) error
Flush() error
Close() error
}
// New creates new provider.
func New(pool func(context.Context) (Conn, error)) cache.Provider {
return func(ctx context.Context, operation string, item *cache.Item) error {
conn, err := pool(ctx)
if err != nil {
return wrapErr(err)
}
defer conn.Close()
key := item.Key.String()
switch operation {
case cache.OperationGet:
data, ttl, err := get(conn, key)
if err != nil {
return err
}
item.TTLInSecond(ttl)
return wrapErr(item.Unmarshal(data))
case cache.OperationSet:
data, err := item.Marshal()
if err != nil {
return wrapErr(err)
}
return set(conn, key, data, int(item.TTL.Seconds()))
case cache.OperationDelete:
return del(conn, key)
}
return wrapErr(cache.ErrOperationNotAllwed)
}
}
func get(conn Conn, key string) ([]byte, int64, error) {
data, err := conn.Do("GET", key)
if err != nil {
return nil, 0, wrapErr(err)
}
if data == nil {
return nil, 0, wrapErr(cache.ErrCacheMiss)
}
v, ok := data.([]byte)
if !ok {
return nil, 0, wrapErr(cache.ErrSourceNotValid)
}
expire, err := conn.Do("TTL", key)
if err != nil {
return v, 0, wrapErr(err)
}
ex, _ := expire.(int64)
return v, ex, nil
}
func set(conn Conn, key string, data []byte, ttl int) error {
if err := conn.Send("SET", key, data); err != nil {
return wrapErr(err)
}
if ttl > 0 {
if err := conn.Send("EXPIRE", key, ttl); err != nil {
return wrapErr(err)
}
}
if err := conn.Flush(); err != nil {
return fmt.Errorf("failed flush then set %s by %w", key, conn.Flush())
}
return nil
}
func del(conn Conn, key string) error {
if _, err := conn.Do("DEL", key); err != nil {
return wrapErr(err)
}
return nil
}
func wrapErr(err error) error {
if err != nil {
return fmt.Errorf("%w: redis pool", err)
}
return nil
}

View File

@@ -0,0 +1,14 @@
package redis_test
import (
"testing"
"gitoa.ru/go-4devs/cache"
"gitoa.ru/go-4devs/cache/provider/redis"
"gitoa.ru/go-4devs/cache/test"
)
func TestRedisPool(t *testing.T) {
t.Parallel()
test.RunSute(t, redis.New(test.RedisClient()), test.WithExpire(cache.ErrCacheMiss))
}

20
provider/redis/redigo.go Normal file
View File

@@ -0,0 +1,20 @@
package redis
import (
"context"
"fmt"
"github.com/gomodule/redigo/redis"
)
// NewPool creates redigo pool.
func NewPool(pool *redis.Pool) func(context.Context) (Conn, error) {
return func(ctx context.Context) (Conn, error) {
conn, err := pool.GetContext(ctx)
if err != nil {
return nil, fmt.Errorf("failed get connect: %w", err)
}
return conn, nil
}
}