-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathwatcher_test.go
101 lines (78 loc) · 2.06 KB
/
watcher_test.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
//go:build with_real_db
// +build with_real_db
package goredis8_test
import (
"context"
"fmt"
"time"
"github.com/go-redis/redis/v8"
trmredis "github.com/avito-tech/go-transaction-manager/drivers/goredis8/v2"
"github.com/avito-tech/go-transaction-manager/trm/v2"
"github.com/avito-tech/go-transaction-manager/trm/v2/manager"
"github.com/avito-tech/go-transaction-manager/trm/v2/settings"
)
// Example demonstrates the watching of updated keys.
func Example_watch() {
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
})
ctx := context.Background()
rdb.FlushDB(ctx)
r := newRepo(rdb, trmredis.DefaultCtxGetter)
u := &user{
ID: uuid1,
Username: "username",
}
trManager := manager.Must(
trmredis.NewDefaultFactory(rdb),
manager.WithSettings(trmredis.MustSettings(
settings.Must(
settings.WithPropagation(trm.PropagationNested)),
trmredis.WithTxDecorator(newWatchDecorator),
trmredis.WithMulti(true),
)),
)
err := r.Save(ctx, u)
checkErr(err)
err = trManager.Do(
ctx,
func(ctx context.Context) error {
u.Username = "new_username"
err = r.Save(ctx, u)
// Rewrite watching key1
rdb.Set(ctx, string(u.ID), "", 0)
return err
},
)
fmt.Println(err)
err = trManager.Do(
ctx,
func(ctx context.Context) error {
u.Username = "new_username"
err = r.Save(ctx, u)
// Unwatch keys
cmd := trmredis.DefaultCtxGetter.DefaultTrOrDB(ctx, nil).(trmredis.Watch).
Unwatch(ctx)
checkErr(cmd.Err())
// Rewrite watching key1
rdb.Set(ctx, string(u.ID), "", 0)
return err
},
)
fmt.Println(err)
// Output: transaction: commit; redis: transaction failed
// <nil>
}
type watchDecoratorExample struct {
trmredis.Cmdable
}
func newWatchDecorator(tx trmredis.Cmdable, _ redis.Cmdable) trmredis.Cmdable {
return &watchDecoratorExample{Cmdable: tx}
}
func (w *watchDecoratorExample) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd {
cmd := w.Watch(ctx, key)
if cmd.Err() != nil {
return cmd
}
return w.Cmdable.Set(ctx, key, value, expiration)
}