Skip to content

Commit 10d6016

Browse files
committed
add refresh support
1 parent dd3b8be commit 10d6016

File tree

2 files changed

+210
-167
lines changed

2 files changed

+210
-167
lines changed

redis.go

Lines changed: 91 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@ package redis
22

33
import (
44
"context"
5-
"encoding/json"
65
"sync"
76
"time"
87

98
"github.com/go-redis/redis"
9+
"github.com/json-iterator/go"
1010
"gopkg.in/session.v2"
1111
)
1212

1313
var (
14-
_ session.ManagerStore = &managerStore{}
15-
_ session.Store = &store{}
14+
_ session.ManagerStore = &managerStore{}
15+
_ session.Store = &store{}
16+
jsonMarshal = jsoniter.Marshal
17+
jsonUnmarshal = jsoniter.Unmarshal
1618
)
1719

1820
// NewRedisStore Create an instance of a redis store
@@ -23,6 +25,11 @@ func NewRedisStore(opt *Options) session.ManagerStore {
2325
return &managerStore{cli: redis.NewClient(opt.redisOptions())}
2426
}
2527

28+
// NewRedisStoreWithCli Create an instance of a redis store
29+
func NewRedisStoreWithCli(cli *redis.Client) session.ManagerStore {
30+
return &managerStore{cli: cli}
31+
}
32+
2633
type managerStore struct {
2734
cli *redis.Client
2835
}
@@ -39,33 +46,43 @@ func (s *managerStore) getValue(sid string) (string, error) {
3946
return cmd.Val(), nil
4047
}
4148

42-
func (s *managerStore) parseValue(value string) (map[string]string, error) {
43-
var values map[string]string
44-
49+
func (s *managerStore) parseValue(value string) (map[string]interface{}, error) {
50+
var values map[string]interface{}
4551
if len(value) > 0 {
46-
err := json.Unmarshal([]byte(value), &values)
52+
err := jsonUnmarshal([]byte(value), &values)
4753
if err != nil {
4854
return nil, err
4955
}
5056
}
5157

5258
if values == nil {
53-
values = make(map[string]string)
59+
values = make(map[string]interface{})
5460
}
5561
return values, nil
5662
}
5763

5864
func (s *managerStore) Create(ctx context.Context, sid string, expired int64) (session.Store, error) {
59-
values := make(map[string]string)
60-
return &store{ctx: ctx, sid: sid, cli: s.cli, expired: expired, values: values}, nil
65+
return &store{
66+
ctx: ctx,
67+
sid: sid,
68+
cli: s.cli,
69+
expired: expired,
70+
values: make(map[string]interface{}),
71+
}, nil
6172
}
6273

6374
func (s *managerStore) Update(ctx context.Context, sid string, expired int64) (session.Store, error) {
6475
value, err := s.getValue(sid)
6576
if err != nil {
6677
return nil, err
6778
} else if value == "" {
68-
return s.Create(ctx, sid, expired)
79+
return &store{
80+
ctx: ctx,
81+
sid: sid,
82+
cli: s.cli,
83+
expired: expired,
84+
values: make(map[string]interface{}),
85+
}, nil
6986
}
7087

7188
cmd := s.cli.Set(sid, value, time.Duration(expired)*time.Second)
@@ -77,37 +94,80 @@ func (s *managerStore) Update(ctx context.Context, sid string, expired int64) (s
7794
if err != nil {
7895
return nil, err
7996
}
80-
81-
return &store{ctx: ctx, sid: sid, cli: s.cli, expired: expired, values: values}, nil
97+
return &store{
98+
ctx: ctx,
99+
sid: sid,
100+
cli: s.cli,
101+
expired: expired,
102+
values: values,
103+
}, nil
82104
}
83105

84106
func (s *managerStore) Delete(_ context.Context, sid string) error {
107+
if ok, err := s.Check(nil, sid); err != nil {
108+
return err
109+
} else if !ok {
110+
return nil
111+
}
112+
85113
cmd := s.cli.Del(sid)
86114
return cmd.Err()
87115
}
88116

89117
func (s *managerStore) Check(_ context.Context, sid string) (bool, error) {
90-
cmd := s.cli.Get(sid)
118+
cmd := s.cli.Exists(sid)
91119
if err := cmd.Err(); err != nil {
92-
if err == redis.Nil {
93-
return false, nil
94-
}
95120
return false, err
96121
}
97-
return true, nil
122+
return cmd.Val() > 0, nil
123+
}
124+
125+
func (s *managerStore) Refresh(ctx context.Context, oldsid, sid string, expired int64) (session.Store, error) {
126+
value, err := s.getValue(oldsid)
127+
if err != nil {
128+
return nil, err
129+
} else if value == "" {
130+
return &store{
131+
ctx: ctx,
132+
sid: sid,
133+
cli: s.cli,
134+
expired: expired,
135+
values: make(map[string]interface{}),
136+
}, nil
137+
}
138+
139+
pipe := s.cli.TxPipeline()
140+
pipe.Set(sid, value, time.Duration(expired)*time.Second)
141+
pipe.Del(oldsid)
142+
_, err = pipe.Exec()
143+
if err != nil {
144+
return nil, err
145+
}
146+
147+
values, err := s.parseValue(value)
148+
if err != nil {
149+
return nil, err
150+
}
151+
return &store{
152+
ctx: ctx,
153+
sid: sid,
154+
cli: s.cli,
155+
expired: expired,
156+
values: values,
157+
}, nil
98158
}
99159

100160
func (s *managerStore) Close() error {
101161
return s.cli.Close()
102162
}
103163

104164
type store struct {
165+
sync.RWMutex
166+
ctx context.Context
105167
sid string
106-
cli *redis.Client
107168
expired int64
108-
values map[string]string
109-
sync.RWMutex
110-
ctx context.Context
169+
values map[string]interface{}
170+
cli *redis.Client
111171
}
112172

113173
func (s *store) Context() context.Context {
@@ -118,20 +178,20 @@ func (s *store) SessionID() string {
118178
return s.sid
119179
}
120180

121-
func (s *store) Set(key, value string) {
181+
func (s *store) Set(key string, value interface{}) {
122182
s.Lock()
123183
s.values[key] = value
124184
s.Unlock()
125185
}
126186

127-
func (s *store) Get(key string) (string, bool) {
187+
func (s *store) Get(key string) (interface{}, bool) {
128188
s.RLock()
129189
defer s.RUnlock()
130190
val, ok := s.values[key]
131191
return val, ok
132192
}
133193

134-
func (s *store) Delete(key string) string {
194+
func (s *store) Delete(key string) interface{} {
135195
s.RLock()
136196
v, ok := s.values[key]
137197
s.RUnlock()
@@ -145,7 +205,7 @@ func (s *store) Delete(key string) string {
145205

146206
func (s *store) Flush() error {
147207
s.Lock()
148-
s.values = make(map[string]string)
208+
s.values = make(map[string]interface{})
149209
s.Unlock()
150210
return s.Save()
151211
}
@@ -155,7 +215,11 @@ func (s *store) Save() error {
155215

156216
s.RLock()
157217
if len(s.values) > 0 {
158-
buf, _ := json.Marshal(s.values)
218+
buf, err := jsonMarshal(s.values)
219+
if err != nil {
220+
s.RUnlock()
221+
return err
222+
}
159223
value = string(buf)
160224
}
161225
s.RUnlock()

0 commit comments

Comments
 (0)