예제 #1
0
파일: client.go 프로젝트: jfrabaute/gohbase
// 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
}
예제 #2
0
파일: info.go 프로젝트: henrylee2cn/gohbase
// 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
}
예제 #3
0
파일: protobuf.go 프로젝트: name5566/leaf
// 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))
	}
}
예제 #4
0
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
}
예제 #5
0
파일: client.go 프로젝트: jfrabaute/gohbase
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()
	}
}