// LocateResource returns the location of the specified resource. func LocateResource(zkquorum string, resource ResourceName) (string, uint16, error) { zks := strings.Split(zkquorum, ",") zkconn, _, err := zk.Connect(zks, time.Duration(sessionTimeout)*time.Second) if err != nil { return "", 0, fmt.Errorf("Error connecting to ZooKeeper at %v: %s", zks, err) } defer zkconn.Close() buf, _, err := zkconn.Get(string(resource)) if err != nil { return "", 0, fmt.Errorf("Failed to read the %s znode: %s", resource, err) } if len(buf) == 0 { log.Fatalf("%s was empty!", resource) } else if buf[0] != 0xFF { return "", 0, fmt.Errorf("The first byte of %s was 0x%x, not 0xFF", resource, buf[0]) } metadataLen := binary.BigEndian.Uint32(buf[1:]) if metadataLen < 1 || metadataLen > 65000 { return "", 0, fmt.Errorf("Invalid metadata length for %s: %d", resource, metadataLen) } buf = buf[1+4+metadataLen:] magic := binary.BigEndian.Uint32(buf) const pbufMagic = 1346524486 // 4 bytes: "PBUF" if magic != pbufMagic { return "", 0, fmt.Errorf("Invalid magic number for %s: %d", resource, magic) } buf = buf[4:] var server *pb.ServerName if resource == Meta { meta := &pb.MetaRegionServer{} err = proto.UnmarshalMerge(buf, meta) if err != nil { return "", 0, fmt.Errorf("Failed to deserialize the MetaRegionServer entry from ZK: %s", err) } server = meta.Server } else { master := &pb.Master{} err = proto.UnmarshalMerge(buf, master) if err != nil { return "", 0, fmt.Errorf("Failed to deserialize the Master entry from ZK: %s", err) } server = master.Master } return *server.HostName, uint16(*server.Port), nil }
// InfoFromCell parses a KeyValue from the meta table and creates the // corresponding Info object. func InfoFromCell(cell *pb.Cell) (*Info, error) { value := cell.Value if len(value) == 0 { return nil, fmt.Errorf("empty value in %q", cell) } else if value[0] != 'P' { return nil, fmt.Errorf("unsupported region info version %d in %q", value[0], cell) } const pbufMagic = 1346524486 // 4 bytes: "PBUF" magic := binary.BigEndian.Uint32(value) if magic != pbufMagic { return nil, fmt.Errorf("invalid magic number in %q", cell) } regInfo := &pb.RegionInfo{} err := proto.UnmarshalMerge(value[4:len(value)-4], regInfo) if err != nil { return nil, fmt.Errorf("failed to decode %q: %s", cell, err) } return &Info{ Table: regInfo.TableName.Qualifier, RegionName: cell.Row, StartKey: regInfo.StartKey, StopKey: regInfo.EndKey, availableLock: sync.Mutex{}, }, nil }
// goroutine safe func (p *Processor) Unmarshal(data []byte) (interface{}, error) { if len(data) < 2 { return nil, errors.New("protobuf data too short") } // id var id uint16 if p.littleEndian { id = binary.LittleEndian.Uint16(data) } else { id = binary.BigEndian.Uint16(data) } if id >= uint16(len(p.msgInfo)) { return nil, fmt.Errorf("message id %v not registered", id) } // msg i := p.msgInfo[id] if i.msgRawHandler != nil { return MsgRaw{id, data[2:]}, nil } else { msg := reflect.New(i.msgType.Elem()).Interface() return msg, proto.UnmarshalMerge(data[2:], msg.(proto.Message)) } }
func (lm *logManager) retrieveLog() (err error) { files, err := ioutil.ReadDir(lm.logDir) if err != nil { return fmt.Errorf("could not retrieve old logs: %v", err) } for _, file := range files { if !file.IsDir() { var startLSN, endLSN = -1, -1 _, err = fmt.Sscanf(file.Name(), logFileFmt, &startLSN, &endLSN) if err != nil { continue } if startLSN != lm.nextLSN || endLSN < startLSN { err = fmt.Errorf("log file %s was not in the expected format", file.Name()) break } filename := fmt.Sprintf("%s/%s", lm.logDir, file.Name()) data, err := ioutil.ReadFile(filename) if err != nil { err = fmt.Errorf("could not read log file %s: %v", filename, err) break } if err = proto.UnmarshalMerge(data, &lm.log); err != nil { err = fmt.Errorf("could not unmarshal log file %s: %v", filename, err) break } lm.nextLSN = len(lm.log.Entry) if nextLSN := endLSN + 1; nextLSN != lm.nextLSN { err = fmt.Errorf("log file %s did not have the right number of entries", filename) break } } } lm.nextLSNToFlush = lm.nextLSN return err }
func (c *Client) receiveRpcs() { var sz [4]byte for { err := c.readFully(sz[:]) if err != nil { c.setSendErr(err) c.errorEncountered() return } buf := make([]byte, binary.BigEndian.Uint32(sz[:])) err = c.readFully(buf) if err != nil { c.setSendErr(err) c.errorEncountered() return } resp := &pb.ResponseHeader{} respLen, nb := proto.DecodeVarint(buf) buf = buf[nb:] err = proto.UnmarshalMerge(buf[:respLen], resp) buf = buf[respLen:] if err != nil { // Failed to deserialize the response header c.setSendErr(err) c.errorEncountered() return } if resp.CallId == nil { // Response doesn't have a call ID log.Error("Response doesn't have a call ID!") c.setSendErr(ErrMissingCallID) c.errorEncountered() return } c.sentRPCsMutex.Lock() rpc, ok := c.sentRPCs[*resp.CallId] c.sentRPCsMutex.Unlock() if !ok { log.WithFields(log.Fields{ "CallId": *resp.CallId, }).Error("Received a response with an unexpected call ID") log.Error("Waiting for responses to the following calls:") c.sentRPCsMutex.Lock() for id, call := range c.sentRPCs { log.Errorf("\t\t%d: %v", id, call) } c.sentRPCsMutex.Unlock() c.setSendErr(fmt.Errorf("HBase sent a response with an unexpected call ID: %d", resp.CallId)) c.errorEncountered() return } var rpcResp proto.Message if resp.Exception == nil { respLen, nb = proto.DecodeVarint(buf) buf = buf[nb:] rpcResp = rpc.NewResponse() err = proto.UnmarshalMerge(buf, rpcResp) buf = buf[respLen:] } else { javaClass := *resp.Exception.ExceptionClassName err = fmt.Errorf("HBase Java exception %s: \n%s", javaClass, *resp.Exception.StackTrace) if _, ok := javaRetryableExceptions[javaClass]; ok { // This is a recoverable error. The client should retry. err = RetryableError{err} } } rpc.GetResultChan() <- hrpc.RPCResult{Msg: rpcResp, Error: err} c.sentRPCsMutex.Lock() delete(c.sentRPCs, *resp.CallId) c.sentRPCsMutex.Unlock() } }