/
chaosrpc.go
124 lines (94 loc) · 3.58 KB
/
chaosrpc.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
package chaosrpc
import (
"errors"
"math/rand"
"go.mercari.io/datastore"
)
// NOTE Please give me a pull request if You can make more chaos (within the specification).
var _ datastore.Middleware = &chaosHandler{}
// New ChaosRPC middleware returns.
func New(s rand.Source) datastore.Middleware {
return &chaosHandler{
r: rand.New(s),
}
}
type chaosHandler struct {
r *rand.Rand
}
func (ch *chaosHandler) raiseError() error {
// Make an error with a 20% rate
if ch.r.Intn(5) == 0 {
return errors.New("error from chaosrpc")
}
return nil
}
func (ch *chaosHandler) AllocateIDs(info *datastore.MiddlewareInfo, keys []datastore.Key) ([]datastore.Key, error) {
if err := ch.raiseError(); err != nil {
return nil, err
}
return info.Next.AllocateIDs(info, keys)
}
func (ch *chaosHandler) PutMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) ([]datastore.Key, error) {
if err := ch.raiseError(); err != nil {
return nil, err
}
return info.Next.PutMultiWithoutTx(info, keys, psList)
}
func (ch *chaosHandler) PutMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) ([]datastore.PendingKey, error) {
if err := ch.raiseError(); err != nil {
return nil, err
}
return info.Next.PutMultiWithTx(info, keys, psList)
}
func (ch *chaosHandler) GetMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) error {
if err := ch.raiseError(); err != nil {
return err
}
return info.Next.GetMultiWithoutTx(info, keys, psList)
}
func (ch *chaosHandler) GetMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) error {
if err := ch.raiseError(); err != nil {
return err
}
return info.Next.GetMultiWithTx(info, keys, psList)
}
func (ch *chaosHandler) DeleteMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key) error {
if err := ch.raiseError(); err != nil {
return err
}
return info.Next.DeleteMultiWithoutTx(info, keys)
}
func (ch *chaosHandler) DeleteMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key) error {
if err := ch.raiseError(); err != nil {
return err
}
return info.Next.DeleteMultiWithTx(info, keys)
}
func (ch *chaosHandler) PostCommit(info *datastore.MiddlewareInfo, tx datastore.Transaction, commit datastore.Commit) error {
// PostCommit don't do RPC
return info.Next.PostCommit(info, tx, commit)
}
func (ch *chaosHandler) PostRollback(info *datastore.MiddlewareInfo, tx datastore.Transaction) error {
// PostRollback don't do RPC
return info.Next.PostRollback(info, tx)
}
func (ch *chaosHandler) Run(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump) datastore.Iterator {
// can't returns error
return info.Next.Run(info, q, qDump)
}
func (ch *chaosHandler) GetAll(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump, psList *[]datastore.PropertyList) ([]datastore.Key, error) {
if err := ch.raiseError(); err != nil {
return nil, err
}
return info.Next.GetAll(info, q, qDump, psList)
}
func (ch *chaosHandler) Next(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump, iter datastore.Iterator, ps *datastore.PropertyList) (datastore.Key, error) {
// Next is not idempotent, don't retry in dsmiddleware/rpcretry.
return info.Next.Next(info, q, qDump, iter, ps)
}
func (ch *chaosHandler) Count(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump) (int, error) {
if err := ch.raiseError(); err != nil {
return 0, err
}
return info.Next.Count(info, q, qDump)
}