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) }
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 }
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 }
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 }
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 }
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 }
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 }
func codecHandle() *codec.MsgpackHandle { var mh codec.MsgpackHandle mh.WriteExt = true return &mh }
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() }