func TestGetExtensionStability(t *testing.T) { check := func(m *pb.MyMessage) bool { ext1, err := proto.GetExtension(m, pb.E_Ext_More) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } ext2, err := proto.GetExtension(m, pb.E_Ext_More) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } return ext1 == ext2 } msg := &pb.MyMessage{Count: proto.Int32(4)} ext0 := &pb.Ext{} if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil { t.Fatalf("Could not set ext1: %s", ext0) } if !check(msg) { t.Errorf("GetExtension() not stable before marshaling") } bb, err := proto.Marshal(msg) if err != nil { t.Fatalf("Marshal() failed: %s", err) } msg1 := &pb.MyMessage{} err = proto.Unmarshal(bb, msg1) if err != nil { t.Fatalf("Unmarshal() failed: %s", err) } if !check(msg1) { t.Errorf("GetExtension() not stable after unmarshaling") } }
func TestRoundTripProto3(t *testing.T) { m := &pb.Message{ Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01 HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" ResultCount: 47, // (0 | 7<<3): 0x38 0x2f TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 Score: 8.1, // (5 | 9<<3): 0x4d <8.1> Key: []uint64{1, 0xdeadbeef}, Nested: &pb.Nested{ Bunny: "Monty", }, } t.Logf(" m: %v", m) b, err := proto.Marshal(m) if err != nil { t.Fatalf("proto.Marshal: %v", err) } t.Logf(" b: %q", b) m2 := new(pb.Message) if err := proto.Unmarshal(b, m2); err != nil { t.Fatalf("proto.Unmarshal: %v", err) } t.Logf("m2: %v", m2) if !proto.Equal(m, m2) { t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) } }
// UnmarshalBinary decodes the object from a binary format. func (data *Data) UnmarshalBinary(buf []byte) error { var pb internal.Data if err := proto.Unmarshal(buf, &pb); err != nil { return err } data.unmarshal(&pb) return nil }
// UnmarshalBinary decodes the object from a binary format. func (si *ShardInfo) UnmarshalBinary(buf []byte) error { var pb internal.ShardInfo if err := proto.Unmarshal(buf, &pb); err != nil { return err } si.unmarshal(&pb) return nil }
// UnmarshalBinary decodes the object from a binary format. func (m *MeasurementFields) UnmarshalBinary(buf []byte) error { var pb internal.MeasurementFields if err := proto.Unmarshal(buf, &pb); err != nil { return err } m.Fields = make(map[string]*Field) for _, f := range pb.Fields { m.Fields[f.GetName()] = &Field{ID: uint8(f.GetID()), Name: f.GetName(), Type: influxql.DataType(f.GetType())} } return nil }
// UnmarshalBinary decodes the object from a binary format. func (s *Series) UnmarshalBinary(buf []byte) error { var pb internal.Series if err := proto.Unmarshal(buf, &pb); err != nil { return err } s.Key = pb.GetKey() s.Tags = make(map[string]string) for _, t := range pb.Tags { s.Tags[t.GetKey()] = t.GetValue() } return nil }
// handleRPCConn reads a command from the connection and executes it. func (r *rpc) handleRPCConn(conn net.Conn) { defer conn.Close() // RPC connections should execute on the leader. If we are not the leader, // proxy the connection to the leader so that clients an connect to any node // in the cluster. r.traceCluster("rpc connection from: %v", conn.RemoteAddr()) if !r.store.IsLeader() { r.proxyLeader(conn.(*net.TCPConn)) return } // Read and execute request. typ, resp, err := func() (internal.RPCType, proto.Message, error) { // Read request size. var sz uint64 if err := binary.Read(conn, binary.BigEndian, &sz); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("read size: %s", err) } if sz == 0 { return 0, nil, fmt.Errorf("invalid message size: %d", sz) } if sz >= MaxMessageSize { return 0, nil, fmt.Errorf("max message size of %d exceeded: %d", MaxMessageSize, sz) } // Read request. buf := make([]byte, sz) if _, err := io.ReadFull(conn, buf); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("read request: %s", err) } // Determine the RPC type rpcType := internal.RPCType(btou64(buf[0:8])) buf = buf[8:] r.traceCluster("recv %v request on: %v", rpcType, conn.RemoteAddr()) switch rpcType { case internal.RPCType_FetchData: var req internal.FetchDataRequest if err := proto.Unmarshal(buf, &req); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("fetch request unmarshal: %v", err) } resp, err := r.handleFetchData(&req) return rpcType, resp, err case internal.RPCType_Join: var req internal.JoinRequest if err := proto.Unmarshal(buf, &req); err != nil { return internal.RPCType_Error, nil, fmt.Errorf("join request unmarshal: %v", err) } resp, err := r.handleJoinRequest(&req) return rpcType, resp, err default: return internal.RPCType_Error, nil, fmt.Errorf("unknown rpc type:%v", rpcType) } }() // Handle unexpected RPC errors if err != nil { resp = &internal.ErrorResponse{ Header: &internal.ResponseHeader{ OK: proto.Bool(false), }, } typ = internal.RPCType_Error } // Set the status header and error message if reply, ok := resp.(Reply); ok { reply.GetHeader().OK = proto.Bool(err == nil) if err != nil { reply.GetHeader().Error = proto.String(err.Error()) } } r.sendResponse(conn, typ, resp) }
// call sends an encoded request to the remote leader and returns // an encoded response value. func (r *rpc) call(dest string, req proto.Message) (proto.Message, error) { // Determine type of request var rpcType internal.RPCType switch t := req.(type) { case *internal.JoinRequest: rpcType = internal.RPCType_Join case *internal.FetchDataRequest: rpcType = internal.RPCType_FetchData default: return nil, fmt.Errorf("unknown rpc request type: %v", t) } // Create a connection to the leader. conn, err := net.DialTimeout("tcp", dest, leaderDialTimeout) if err != nil { return nil, fmt.Errorf("rpc dial: %v", err) } defer conn.Close() // Write a marker byte for rpc messages. _, err = conn.Write([]byte{MuxRPCHeader}) if err != nil { return nil, err } b, err := proto.Marshal(req) if err != nil { return nil, fmt.Errorf("rpc marshal: %v", err) } // Write request size & bytes. if _, err := conn.Write(r.pack(rpcType, b)); err != nil { return nil, fmt.Errorf("write %v rpc: %s", rpcType, err) } data, err := ioutil.ReadAll(conn) if err != nil { return nil, fmt.Errorf("read %v rpc: %v", rpcType, err) } // Should always have a size and type if exp := 16; len(data) < exp { r.traceCluster("recv: %v", string(data)) return nil, fmt.Errorf("rpc %v failed: short read: got %v, exp %v", rpcType, len(data), exp) } sz := btou64(data[0:8]) if len(data[8:]) != int(sz) { r.traceCluster("recv: %v", string(data)) return nil, fmt.Errorf("rpc %v failed: short read: got %v, exp %v", rpcType, len(data[8:]), sz) } // See what response type we got back, could get a general error response rpcType = internal.RPCType(btou64(data[8:16])) data = data[16:] var resp proto.Message switch rpcType { case internal.RPCType_Join: resp = &internal.JoinResponse{} case internal.RPCType_FetchData: resp = &internal.FetchDataResponse{} case internal.RPCType_Error: resp = &internal.ErrorResponse{} default: return nil, fmt.Errorf("unknown rpc response type: %v", rpcType) } if err := proto.Unmarshal(data, resp); err != nil { return nil, fmt.Errorf("rpc unmarshal: %v", err) } if reply, ok := resp.(Reply); ok { if !reply.GetHeader().GetOK() { return nil, fmt.Errorf("rpc %v failed: %s", rpcType, reply.GetHeader().GetError()) } } return resp, nil }