go.mercari.io/datastore@v1.8.2/dsmiddleware/chaosrpc/chaosrpc.go (about) 1 package chaosrpc 2 3 import ( 4 "errors" 5 "math/rand" 6 7 "go.mercari.io/datastore" 8 ) 9 10 // NOTE Please give me a pull request if You can make more chaos (within the specification). 11 12 var _ datastore.Middleware = &chaosHandler{} 13 14 // New ChaosRPC middleware returns. 15 func New(s rand.Source) datastore.Middleware { 16 return &chaosHandler{ 17 r: rand.New(s), 18 } 19 } 20 21 type chaosHandler struct { 22 r *rand.Rand 23 } 24 25 func (ch *chaosHandler) raiseError() error { 26 // Make an error with a 20% rate 27 if ch.r.Intn(5) == 0 { 28 return errors.New("error from chaosrpc") 29 } 30 31 return nil 32 } 33 34 func (ch *chaosHandler) AllocateIDs(info *datastore.MiddlewareInfo, keys []datastore.Key) ([]datastore.Key, error) { 35 if err := ch.raiseError(); err != nil { 36 return nil, err 37 } 38 39 return info.Next.AllocateIDs(info, keys) 40 } 41 42 func (ch *chaosHandler) PutMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) ([]datastore.Key, error) { 43 if err := ch.raiseError(); err != nil { 44 return nil, err 45 } 46 47 return info.Next.PutMultiWithoutTx(info, keys, psList) 48 } 49 50 func (ch *chaosHandler) PutMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) ([]datastore.PendingKey, error) { 51 if err := ch.raiseError(); err != nil { 52 return nil, err 53 } 54 55 return info.Next.PutMultiWithTx(info, keys, psList) 56 } 57 58 func (ch *chaosHandler) GetMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) error { 59 if err := ch.raiseError(); err != nil { 60 return err 61 } 62 63 return info.Next.GetMultiWithoutTx(info, keys, psList) 64 } 65 66 func (ch *chaosHandler) GetMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key, psList []datastore.PropertyList) error { 67 if err := ch.raiseError(); err != nil { 68 return err 69 } 70 71 return info.Next.GetMultiWithTx(info, keys, psList) 72 } 73 74 func (ch *chaosHandler) DeleteMultiWithoutTx(info *datastore.MiddlewareInfo, keys []datastore.Key) error { 75 if err := ch.raiseError(); err != nil { 76 return err 77 } 78 79 return info.Next.DeleteMultiWithoutTx(info, keys) 80 } 81 82 func (ch *chaosHandler) DeleteMultiWithTx(info *datastore.MiddlewareInfo, keys []datastore.Key) error { 83 if err := ch.raiseError(); err != nil { 84 return err 85 } 86 87 return info.Next.DeleteMultiWithTx(info, keys) 88 } 89 90 func (ch *chaosHandler) PostCommit(info *datastore.MiddlewareInfo, tx datastore.Transaction, commit datastore.Commit) error { 91 // PostCommit don't do RPC 92 return info.Next.PostCommit(info, tx, commit) 93 } 94 95 func (ch *chaosHandler) PostRollback(info *datastore.MiddlewareInfo, tx datastore.Transaction) error { 96 // PostRollback don't do RPC 97 return info.Next.PostRollback(info, tx) 98 } 99 100 func (ch *chaosHandler) Run(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump) datastore.Iterator { 101 // can't returns error 102 return info.Next.Run(info, q, qDump) 103 } 104 105 func (ch *chaosHandler) GetAll(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump, psList *[]datastore.PropertyList) ([]datastore.Key, error) { 106 if err := ch.raiseError(); err != nil { 107 return nil, err 108 } 109 110 return info.Next.GetAll(info, q, qDump, psList) 111 } 112 113 func (ch *chaosHandler) Next(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump, iter datastore.Iterator, ps *datastore.PropertyList) (datastore.Key, error) { 114 // Next is not idempotent, don't retry in dsmiddleware/rpcretry. 115 return info.Next.Next(info, q, qDump, iter, ps) 116 } 117 118 func (ch *chaosHandler) Count(info *datastore.MiddlewareInfo, q datastore.Query, qDump *datastore.QueryDump) (int, error) { 119 if err := ch.raiseError(); err != nil { 120 return 0, err 121 } 122 123 return info.Next.Count(info, q, qDump) 124 }