github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/go-hbase/action.go (about) 1 package hbase 2 3 import ( 4 pb "github.com/insionng/yougam/libraries/golang/protobuf/proto" 5 "github.com/insionng/yougam/libraries/juju/errors" 6 "github.com/insionng/yougam/libraries/ngaut/log" 7 "github.com/insionng/yougam/libraries/pingcap/go-hbase/proto" 8 ) 9 10 type action interface { 11 ToProto() pb.Message 12 } 13 14 func (c *client) innerCall(table, row []byte, action action, useCache bool) (*call, error) { 15 region, err := c.LocateRegion(table, row, useCache) 16 if err != nil { 17 return nil, errors.Trace(err) 18 } 19 20 conn, err := c.getClientConn(region.Server) 21 if err != nil { 22 return nil, errors.Trace(err) 23 } 24 25 regionSpecifier := &proto.RegionSpecifier{ 26 Type: proto.RegionSpecifier_REGION_NAME.Enum(), 27 Value: []byte(region.Name), 28 } 29 30 var cl *call 31 switch a := action.(type) { 32 case *Get: 33 cl = newCall(&proto.GetRequest{ 34 Region: regionSpecifier, 35 Get: a.ToProto().(*proto.Get), 36 }) 37 case *Put, *Delete: 38 cl = newCall(&proto.MutateRequest{ 39 Region: regionSpecifier, 40 Mutation: a.ToProto().(*proto.MutationProto), 41 }) 42 43 case *CoprocessorServiceCall: 44 cl = newCall(&proto.CoprocessorServiceRequest{ 45 Region: regionSpecifier, 46 Call: a.ToProto().(*proto.CoprocessorServiceCall), 47 }) 48 default: 49 return nil, errors.Errorf("Unknown action - %T - %v", action, action) 50 } 51 52 err = conn.call(cl) 53 if err != nil { 54 // If failed, remove bad server conn cache. 55 cachedKey := cachedConnKey(region.Server, ClientService) 56 delete(c.cachedConns, cachedKey) 57 return nil, errors.Trace(err) 58 } 59 60 return cl, nil 61 } 62 63 func (c *client) innerDo(table, row []byte, action action, useCache bool) (pb.Message, error) { 64 // Try to create and send a new resuqest call. 65 cl, err := c.innerCall(table, row, action, useCache) 66 if err != nil { 67 log.Warnf("inner call failed - %v", errors.ErrorStack(err)) 68 return nil, errors.Trace(err) 69 } 70 71 // Wait and receive the result. 72 return <-cl.responseCh, nil 73 } 74 75 func (c *client) do(table, row []byte, action action, useCache bool) (pb.Message, error) { 76 var ( 77 result pb.Message 78 err error 79 ) 80 81 LOOP: 82 for i := 0; i < c.maxRetries; i++ { 83 result, err = c.innerDo(table, row, action, useCache) 84 if err == nil { 85 switch r := result.(type) { 86 case *exception: 87 err = errors.New(r.msg) 88 // If get an execption response, clean old region cache. 89 c.CleanRegionCache(table) 90 default: 91 break LOOP 92 } 93 } 94 95 useCache = false 96 log.Warnf("Retrying action for the %d time(s), error - %v", i+1, errors.ErrorStack(err)) 97 retrySleep(i + 1) 98 } 99 100 return result, errors.Trace(err) 101 }