-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathservice.go
133 lines (109 loc) · 2.96 KB
/
service.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package easyredis
import (
"context"
"encoding/json"
"fmt"
"strconv"
"time"
"github.com/go-redis/redis/v8"
"github.com/pkg/errors"
)
// Service is a wrapper around go-redis for easy read and write
type Service struct {
client *redis.Client
}
// New instantiates a new service.
func New(client *redis.Client) *Service {
return &Service{
client: client,
}
}
// ConnectToRedis instantiates a new go-redis client.
func ConnectToRedis(host, port, db, password string) (*redis.Client, error) {
const errMessage = "failed to initialize redis client"
redisAddr := fmt.Sprintf("%s:%s", host, port)
redisDB, err := strconv.Atoi(db)
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
redisClient := redis.NewClient(&redis.Options{
Addr: redisAddr,
Password: password,
DB: redisDB,
})
pingErr := redisClient.Ping(context.Background()).Err()
if pingErr != nil {
return nil, errors.Wrap(pingErr, errMessage)
}
return redisClient, nil
}
// Get returns a value for given key from redis.
//
// ctx should have a timeout
// key
func (s *Service) Get(ctx context.Context, key string) ([]byte, error) {
const errMessage = "failed to get value from redis"
result, err := s.client.Exists(ctx, key).Uint64()
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
existsInRedis := result == 1
if !existsInRedis {
return nil, errors.Wrap(ErrRedisKeyNotFound, errMessage)
}
val, err := s.client.Get(ctx, key).Bytes()
if err != nil {
return nil, errors.Wrap(err, errMessage)
}
return val, nil
}
// Set writes the given value to redis as json with the given TTL.
//
// ctx should have a timeout
//
// ttl is the time until the data should expire
//
// key is the key that is being used to store the data
//
// value can be any value
func (s *Service) Set(ctx context.Context, ttl time.Duration, key string, val interface{}) error {
const errMessage = "failed to write value to redis"
toCache, err := json.Marshal(val)
if err != nil {
return errors.Wrap(err, errMessage)
}
err = s.client.SetEX(ctx, key, toCache, ttl).Err()
if err != nil {
return errors.Wrap(err, errMessage)
}
return nil
}
// SetJSON the given value to redis as json with the given TTL.
//
// ctx should have a timeout
//
// ttl is the time until the data should expire
//
// key is the key that is being used to store the data
//
// value must be a json object ([]byte)
func (s *Service) SetJSON(ctx context.Context, ttl time.Duration, key string, val []byte) error {
const errMessage = "failed to write json value to redis"
err := s.client.SetEX(ctx, key, val, ttl).Err()
if err != nil {
return errors.Wrap(err, errMessage)
}
return nil
}
// Exists returns true if the given key exists in redis.
//
// ctx should have a timeout
//
// key is the key that is being used to store the data
func (s *Service) Exists(ctx context.Context, key string) (bool, error) {
result, err := s.client.Exists(ctx, key).Uint64()
if err != nil {
return false, err
}
return result == 1, nil
}