func TestSpanMsgPack(t *testing.T) {
	span := Span{Id: TestId("33f25a1a750a471db5bafa59309d7d6f"),
		SpanData: SpanData{
			Begin:       1234,
			End:         5678,
			Description: "getFileDescriptors",
			Parents:     []SpanId{},
			TracerId:    "testTracerId",
		}}
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	w := bytes.NewBuffer(make([]byte, 0, 2048))
	enc := codec.NewEncoder(w, mh)
	err := enc.Encode(span)
	if err != nil {
		t.Fatal("Error encoding span as msgpack: " + err.Error())
	}
	buf := w.Bytes()
	fmt.Printf("span: %s\n", hex.EncodeToString(buf))
	mh = new(codec.MsgpackHandle)
	mh.WriteExt = true
	dec := codec.NewDecoder(bytes.NewReader(buf), mh)
	var span2 Span
	err = dec.Decode(&span2)
	if err != nil {
		t.Fatal("Failed to reverse msgpack encoding for " + span.String())
	}
	ExpectSpansEqual(t, &span, &span2)
}
Example #2
0
func (cdc *HrpcClientCodec) ReadResponseBody(body interface{}) error {
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	dec := codec.NewDecoder(io.LimitReader(cdc.rwc, int64(cdc.length)), mh)
	err := dec.Decode(body)
	if err != nil {
		return errors.New(fmt.Sprintf("Failed to read response body: %s",
			err.Error()))
	}
	return nil
}
Example #3
0
func (cdc *HrpcServerCodec) WriteResponse(resp *rpc.Response, msg interface{}) error {
	var err error
	buf := EMPTY
	if msg != nil {
		mh := new(codec.MsgpackHandle)
		mh.WriteExt = true
		w := bytes.NewBuffer(make([]byte, 0, 128))
		enc := codec.NewEncoder(w, mh)
		err := enc.Encode(msg)
		if err != nil {
			return createErrAndWarn(cdc.lg, fmt.Sprintf("Failed to marshal "+
				"response message: %s", err.Error()))
		}
		buf = w.Bytes()
	}
	hdr := common.HrpcResponseHeader{}
	hdr.MethodId = common.HrpcMethodNameToId(resp.ServiceMethod)
	hdr.Seq = resp.Seq
	hdr.ErrLength = uint32(len(resp.Error))
	hdr.Length = uint32(len(buf))
	writer := bufio.NewWriterSize(cdc.conn, 256)
	err = binary.Write(writer, binary.LittleEndian, &hdr)
	if err != nil {
		return createErrAndWarn(cdc.lg, fmt.Sprintf("Failed to write response "+
			"header: %s", err.Error()))
	}
	if hdr.ErrLength > 0 {
		_, err = io.WriteString(writer, resp.Error)
		if err != nil {
			return createErrAndWarn(cdc.lg, fmt.Sprintf("Failed to write error "+
				"string: %s", err.Error()))
		}
	}
	if hdr.Length > 0 {
		var length int
		length, err = writer.Write(buf)
		if err != nil {
			return createErrAndWarn(cdc.lg, fmt.Sprintf("Failed to write response "+
				"message: %s", err.Error()))
		}
		if uint32(length) != hdr.Length {
			return createErrAndWarn(cdc.lg, fmt.Sprintf("Failed to write all of "+
				"response message: %s", err.Error()))
		}
	}
	err = writer.Flush()
	if err != nil {
		return createErrAndWarn(cdc.lg, fmt.Sprintf("Failed to write the response "+
			"bytes: %s", err.Error()))
	}
	return nil
}
func (shd *shard) decodeSpan(sid common.SpanId, buf []byte) (*common.Span, error) {
	r := bytes.NewBuffer(buf)
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	decoder := codec.NewDecoder(r, mh)
	data := common.SpanData{}
	err := decoder.Decode(&data)
	if err != nil {
		return nil, err
	}
	if data.Parents == nil {
		data.Parents = []common.SpanId{}
	}
	return &common.Span{Id: common.SpanId(sid), SpanData: data}, nil
}
Example #5
0
func (shd *ShardLoader) writeShardInfo(info *ShardInfo) error {
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	w := new(bytes.Buffer)
	enc := codec.NewEncoder(w, mh)
	err := enc.Encode(info)
	if err != nil {
		return errors.New(fmt.Sprintf("msgpack encoding error: %s",
			err.Error()))
	}
	err = shd.ldb.Put(shd.dld.writeOpts, []byte{SHARD_INFO_KEY}, w.Bytes())
	if err != nil {
		return errors.New(fmt.Sprintf("leveldb write error: %s",
			err.Error()))
	}
	return nil
}
Example #6
0
func (cdc *HrpcServerCodec) ReadRequestBody(body interface{}) error {
	if cdc.lg.TraceEnabled() {
		cdc.lg.Tracef("Reading HRPC %d-byte request body from %s\n",
			cdc.length, cdc.conn.RemoteAddr())
	}
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	dec := codec.NewDecoder(io.LimitReader(cdc.conn, int64(cdc.length)), mh)
	err := dec.Decode(body)
	if err != nil {
		return createErrAndWarn(cdc.lg, fmt.Sprintf("Failed to read request "+
			"body from %s: %s", cdc.conn.RemoteAddr(), err.Error()))
	}
	if cdc.lg.TraceEnabled() {
		cdc.lg.Tracef("Read body from %s: %s\n",
			cdc.conn.RemoteAddr(), asJson(&body))
	}
	return nil
}
Example #7
0
func (cdc *HrpcClientCodec) WriteRequest(req *rpc.Request, msg interface{}) error {
	methodId := common.HrpcMethodNameToId(req.ServiceMethod)
	if methodId == common.METHOD_ID_NONE {
		return errors.New(fmt.Sprintf("HrpcClientCodec: Unknown method name %s",
			req.ServiceMethod))
	}
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	w := bytes.NewBuffer(make([]byte, 0, 2048))
	enc := codec.NewEncoder(w, mh)
	err := enc.Encode(msg)
	if err != nil {
		return errors.New(fmt.Sprintf("HrpcClientCodec: Unable to marshal "+
			"message as msgpack: %s", err.Error()))
	}
	buf := w.Bytes()
	if len(buf) > common.MAX_HRPC_BODY_LENGTH {
		return errors.New(fmt.Sprintf("HrpcClientCodec: message body is %d "+
			"bytes, but the maximum message size is %d bytes.",
			len(buf), common.MAX_HRPC_BODY_LENGTH))
	}
	hdr := common.HrpcRequestHeader{
		Magic:    common.HRPC_MAGIC,
		MethodId: methodId,
		Seq:      req.Seq,
		Length:   uint32(len(buf)),
	}
	err = binary.Write(cdc.rwc, binary.LittleEndian, &hdr)
	if err != nil {
		return errors.New(fmt.Sprintf("Error writing header bytes: %s",
			err.Error()))
	}
	_, err = cdc.rwc.Write(buf)
	if err != nil {
		return errors.New(fmt.Sprintf("Error writing body bytes: %s",
			err.Error()))
	}
	return nil
}
Example #8
0
func (shd *ShardLoader) readShardInfo() (*ShardInfo, error) {
	buf, err := shd.ldb.Get(shd.dld.readOpts, []byte{SHARD_INFO_KEY})
	if err != nil {
		return nil, errors.New(fmt.Sprintf("readShardInfo(%s): failed to "+
			"read shard info key: %s", shd.path, err.Error()))
	}
	if len(buf) == 0 {
		return nil, errors.New(fmt.Sprintf("readShardInfo(%s): got zero-"+
			"length value for shard info key.", shd.path))
	}
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	r := bytes.NewBuffer(buf)
	decoder := codec.NewDecoder(r, mh)
	shardInfo := &ShardInfo{
		LayoutVersion: UNKNOWN_LAYOUT_VERSION,
	}
	err = decoder.Decode(shardInfo)
	if err != nil {
		return nil, errors.New(fmt.Sprintf("readShardInfo(%s): msgpack "+
			"decoding failed for shard info key: %s", shd.path, err.Error()))
	}
	return shardInfo, nil
}
Example #9
0
func codecHandle() *codec.MsgpackHandle {
	var mh codec.MsgpackHandle
	mh.WriteExt = true
	return &mh
}
Example #10
0
func (cdc *HrpcClientCodec) WriteRequest(rr *rpc.Request, msg interface{}) error {
	methodId := common.HrpcMethodNameToId(rr.ServiceMethod)
	if methodId == common.METHOD_ID_NONE {
		return errors.New(fmt.Sprintf("HrpcClientCodec: Unknown method name %s",
			rr.ServiceMethod))
	}
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	w := bytes.NewBuffer(make([]byte, 0, 2048))

	var err error
	enc := codec.NewEncoder(w, mh)
	if methodId == common.METHOD_ID_WRITE_SPANS {
		spans := msg.([]*common.Span)
		req := &common.WriteSpansReq{
			NumSpans: len(spans),
		}
		err = enc.Encode(req)
		if err != nil {
			return errors.New(fmt.Sprintf("HrpcClientCodec: Unable to marshal "+
				"message as msgpack: %s", err.Error()))
		}
		for spanIdx := range spans {
			err = enc.Encode(spans[spanIdx])
			if err != nil {
				return errors.New(fmt.Sprintf("HrpcClientCodec: Unable to marshal "+
					"span %d out of %d as msgpack: %s", spanIdx, len(spans), err.Error()))
			}
		}
	} else {
		err = enc.Encode(msg)
		if err != nil {
			return errors.New(fmt.Sprintf("HrpcClientCodec: Unable to marshal "+
				"message as msgpack: %s", err.Error()))
		}
	}
	buf := w.Bytes()
	if len(buf) > common.MAX_HRPC_BODY_LENGTH {
		return errors.New(fmt.Sprintf("HrpcClientCodec: message body is %d "+
			"bytes, but the maximum message size is %d bytes.",
			len(buf), common.MAX_HRPC_BODY_LENGTH))
	}
	hdr := common.HrpcRequestHeader{
		Magic:    common.HRPC_MAGIC,
		MethodId: methodId,
		Seq:      rr.Seq,
		Length:   uint32(len(buf)),
	}
	err = binary.Write(cdc.rwc, binary.LittleEndian, &hdr)
	if err != nil {
		return errors.New(fmt.Sprintf("Error writing header bytes: %s",
			err.Error()))
	}
	if cdc.testHooks != nil && cdc.testHooks.HandleWriteRequestBody != nil {
		cdc.testHooks.HandleWriteRequestBody()
	}
	_, err = cdc.rwc.Write(buf)
	if err != nil {
		return errors.New(fmt.Sprintf("Error writing body bytes: %s",
			err.Error()))
	}
	return nil
}
func doWriteSpans(name string, N int, maxSpansPerRpc uint32, b *testing.B) {
	htraceBld := &MiniHTracedBuilder{Name: "doWriteSpans",
		Cnf: map[string]string{
			conf.HTRACE_LOG_LEVEL:         "INFO",
			conf.HTRACE_NUM_HRPC_HANDLERS: "20",
		},
		WrittenSpans: common.NewSemaphore(int64(1 - N)),
	}
	ht, err := htraceBld.Build()
	if err != nil {
		panic(err)
	}
	defer ht.Close()
	rnd := rand.New(rand.NewSource(1))
	allSpans := make([]*common.Span, N)
	for n := 0; n < N; n++ {
		allSpans[n] = test.NewRandomSpan(rnd, allSpans[0:n])
	}
	// Determine how many calls to WriteSpans we should make.  Each writeSpans
	// message should be small enough so that it doesn't exceed the max RPC
	// body length limit.  TODO: a production-quality golang client would do
	// this internally rather than needing us to do it here in the unit test.
	bodyLen := (4 * common.MAX_HRPC_BODY_LENGTH) / 5
	reqs := make([][]*common.Span, 0, 4)
	curReq := -1
	curReqLen := bodyLen
	var curReqSpans uint32
	mh := new(codec.MsgpackHandle)
	mh.WriteExt = true
	var mbuf [8192]byte
	buf := mbuf[:0]
	enc := codec.NewEncoderBytes(&buf, mh)
	for n := 0; n < N; n++ {
		span := allSpans[n]
		if (curReqSpans >= maxSpansPerRpc) ||
			(curReqLen >= bodyLen) {
			reqs = append(reqs, make([]*common.Span, 0, 16))
			curReqLen = 0
			curReq++
			curReqSpans = 0
		}
		buf = mbuf[:0]
		enc.ResetBytes(&buf)
		err := enc.Encode(span)
		if err != nil {
			panic(fmt.Sprintf("Error encoding span %s: %s\n",
				span.String(), err.Error()))
		}
		bufLen := len(buf)
		if bufLen > (bodyLen / 5) {
			panic(fmt.Sprintf("Span too long at %d bytes\n", bufLen))
		}
		curReqLen += bufLen
		reqs[curReq] = append(reqs[curReq], span)
		curReqSpans++
	}
	ht.Store.lg.Infof("num spans: %d.  num WriteSpansReq calls: %d\n", N, len(reqs))
	var hcl *htrace.Client
	hcl, err = htrace.NewClient(ht.ClientConf(), nil)
	if err != nil {
		panic(fmt.Sprintf("failed to create client: %s", err.Error()))
	}
	defer hcl.Close()

	// Reset the timer to avoid including the time required to create new
	// random spans in the benchmark total.
	if b != nil {
		b.ResetTimer()
	}

	// Write many random spans.
	for reqIdx := range reqs {
		go func(i int) {
			err = hcl.WriteSpans(reqs[i])
			if err != nil {
				panic(fmt.Sprintf("failed to send WriteSpans request %d: %s",
					i, err.Error()))
			}
		}(reqIdx)
	}
	// Wait for all the spans to be written.
	ht.Store.WrittenSpans.Wait()
}