*: proto refactoring

This commit is contained in:
Xiang Li 2014-10-11 20:41:00 +08:00
parent 2b03d35ab9
commit f98fbbfc14
6 changed files with 68 additions and 63 deletions

View File

@ -10,7 +10,7 @@
It has these top-level messages: It has these top-level messages:
Request Request
Info Metadata
*/ */
package etcdserverpb package etcdserverpb
@ -52,14 +52,14 @@ func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) } func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {} func (*Request) ProtoMessage() {}
type Info struct { type Metadata struct {
ID uint64 `protobuf:"varint,1,req" json:"ID"` NodeID uint64 `protobuf:"varint,1,req" json:"NodeID"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
} }
func (m *Info) Reset() { *m = Info{} } func (m *Metadata) Reset() { *m = Metadata{} }
func (m *Info) String() string { return proto.CompactTextString(m) } func (m *Metadata) String() string { return proto.CompactTextString(m) }
func (*Info) ProtoMessage() {} func (*Metadata) ProtoMessage() {}
func init() { func init() {
} }
@ -388,7 +388,7 @@ func (m *Request) Unmarshal(data []byte) error {
} }
return nil return nil
} }
func (m *Info) Unmarshal(data []byte) error { func (m *Metadata) Unmarshal(data []byte) error {
l := len(data) l := len(data)
index := 0 index := 0
for index < l { for index < l {
@ -417,7 +417,7 @@ func (m *Info) Unmarshal(data []byte) error {
} }
b := data[index] b := data[index]
index++ index++
m.ID |= (uint64(b) & 0x7F) << shift m.NodeID |= (uint64(b) & 0x7F) << shift
if b < 0x80 { if b < 0x80 {
break break
} }
@ -475,10 +475,10 @@ func (m *Request) Size() (n int) {
} }
return n return n
} }
func (m *Info) Size() (n int) { func (m *Metadata) Size() (n int) {
var l int var l int
_ = l _ = l
n += 1 + sovEtcdserver(uint64(m.ID)) n += 1 + sovEtcdserver(uint64(m.NodeID))
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized) n += len(m.XXX_unrecognized)
} }
@ -609,7 +609,7 @@ func (m *Request) MarshalTo(data []byte) (n int, err error) {
} }
return i, nil return i, nil
} }
func (m *Info) Marshal() (data []byte, err error) { func (m *Metadata) Marshal() (data []byte, err error) {
size := m.Size() size := m.Size()
data = make([]byte, size) data = make([]byte, size)
n, err := m.MarshalTo(data) n, err := m.MarshalTo(data)
@ -619,14 +619,14 @@ func (m *Info) Marshal() (data []byte, err error) {
return data[:n], nil return data[:n], nil
} }
func (m *Info) MarshalTo(data []byte) (n int, err error) { func (m *Metadata) MarshalTo(data []byte) (n int, err error) {
var i int var i int
_ = i _ = i
var l int var l int
_ = l _ = l
data[i] = 0x8 data[i] = 0x8
i++ i++
i = encodeVarintEtcdserver(data, i, uint64(m.ID)) i = encodeVarintEtcdserver(data, i, uint64(m.NodeID))
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
i += copy(data[i:], m.XXX_unrecognized) i += copy(data[i:], m.XXX_unrecognized)
} }

View File

@ -26,6 +26,6 @@ message Request {
required bool Stream = 16 [(gogoproto.nullable) = false]; required bool Stream = 16 [(gogoproto.nullable) = false];
} }
message Info { message Metadata {
required uint64 ID = 1 [(gogoproto.nullable) = false]; required uint64 NodeID = 1 [(gogoproto.nullable) = false];
} }

View File

@ -12,6 +12,7 @@ import (
"github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/go.net/context" "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/go.net/context"
"github.com/coreos/etcd/discovery" "github.com/coreos/etcd/discovery"
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
"github.com/coreos/etcd/pkg/pbutil"
"github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft"
"github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/snap" "github.com/coreos/etcd/snap"
@ -384,11 +385,7 @@ func (s *EtcdServer) sync(timeout time.Duration) {
ID: GenID(), ID: GenID(),
Time: time.Now().UnixNano(), Time: time.Now().UnixNano(),
} }
data, err := req.Marshal() data := pbutil.MustMarshal(&req)
if err != nil {
log.Printf("marshal request %#v error: %v", req, err)
return
}
// There is no promise that node has leader when do SYNC request, // There is no promise that node has leader when do SYNC request,
// so it uses goroutine to propose. // so it uses goroutine to propose.
go func() { go func() {
@ -447,15 +444,11 @@ func (s *EtcdServer) apply(es []raftpb.Entry) uint64 {
switch e.Type { switch e.Type {
case raftpb.EntryNormal: case raftpb.EntryNormal:
var r pb.Request var r pb.Request
if err := r.Unmarshal(e.Data); err != nil { pbutil.MustUnmarshal(&r, e.Data)
panic("TODO: this is bad, what do we do about it?")
}
s.w.Trigger(r.ID, s.applyRequest(r)) s.w.Trigger(r.ID, s.applyRequest(r))
case raftpb.EntryConfChange: case raftpb.EntryConfChange:
var cc raftpb.ConfChange var cc raftpb.ConfChange
if err := cc.Unmarshal(e.Data); err != nil { pbutil.MustUnmarshal(&cc, e.Data)
panic("TODO: this is bad, what do we do about it?")
}
s.applyConfChange(cc) s.applyConfChange(cc)
s.w.Trigger(cc.ID, nil) s.w.Trigger(cc.ID, nil)
default: default:
@ -541,12 +534,9 @@ func (s *EtcdServer) snapshot(snapi uint64, snapnodes []uint64) {
} }
func startNode(cfg *ServerConfig) (n raft.Node, w *wal.WAL) { func startNode(cfg *ServerConfig) (n raft.Node, w *wal.WAL) {
i := pb.Info{ID: cfg.ID()} var err error
b, err := i.Marshal() metadata := pbutil.MustMarshal(&pb.Metadata{NodeID: cfg.ID()})
if err != nil { if w, err = wal.Create(cfg.WALDir(), metadata); err != nil {
log.Fatal(err)
}
if w, err = wal.Create(cfg.WALDir(), b); err != nil {
log.Fatal(err) log.Fatal(err)
} }
ids := cfg.Cluster.IDs() ids := cfg.Cluster.IDs()
@ -568,15 +558,15 @@ func restartNode(cfg *ServerConfig, index uint64, snapshot *raftpb.Snapshot) (n
if w, err = wal.OpenAtIndex(cfg.WALDir(), index); err != nil { if w, err = wal.OpenAtIndex(cfg.WALDir(), index); err != nil {
log.Fatal(err) log.Fatal(err)
} }
md, st, ents, err := w.ReadAll() wmetadata, st, ents, err := w.ReadAll()
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
var info pb.Info
if err := info.Unmarshal(md); err != nil { var metadata pb.Metadata
log.Fatal(err) pbutil.MustUnmarshal(&metadata, wmetadata)
}
n = raft.RestartNode(info.ID, 10, 1, snapshot, st, ents) n = raft.RestartNode(metadata.NodeID, 10, 1, snapshot, st, ents)
return return
} }

25
pkg/pbutil/pbutil.go Normal file
View File

@ -0,0 +1,25 @@
package pbutil
import "log"
type Marshaler interface {
Marshal() (data []byte, err error)
}
type Unmarshaler interface {
Unmarshal(data []byte) error
}
func MustMarshal(m Marshaler) []byte {
d, err := m.Marshal()
if err != nil {
log.Panicf("pbutil: %v", err)
}
return d
}
func MustUnmarshal(um Unmarshaler, data []byte) {
if err := um.Unmarshal(data); err != nil {
log.Panicf("pbutil: %v", err)
}
}

View File

@ -7,6 +7,7 @@ import (
"io" "io"
"github.com/coreos/etcd/pkg/crc" "github.com/coreos/etcd/pkg/crc"
"github.com/coreos/etcd/pkg/pbutil"
"github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/wal/walpb" "github.com/coreos/etcd/wal/walpb"
) )
@ -60,19 +61,13 @@ func (d *decoder) close() error {
func mustUnmarshalEntry(d []byte) raftpb.Entry { func mustUnmarshalEntry(d []byte) raftpb.Entry {
var e raftpb.Entry var e raftpb.Entry
if err := e.Unmarshal(d); err != nil { pbutil.MustUnmarshal(&e, d)
// crc matched, but we cannot unmarshal the struct?!
// we must be the next winner of the $1B lottery.
panic(err)
}
return e return e
} }
func mustUnmarshalState(d []byte) raftpb.HardState { func mustUnmarshalState(d []byte) raftpb.HardState {
var s raftpb.HardState var s raftpb.HardState
if err := s.Unmarshal(d); err != nil { pbutil.MustUnmarshal(&s, d)
panic(err)
}
return s return s
} }

View File

@ -26,6 +26,7 @@ import (
"reflect" "reflect"
"sort" "sort"
"github.com/coreos/etcd/pkg/pbutil"
"github.com/coreos/etcd/raft" "github.com/coreos/etcd/raft"
"github.com/coreos/etcd/raft/raftpb" "github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/wal/walpb" "github.com/coreos/etcd/wal/walpb"
@ -56,7 +57,7 @@ var (
// The WAL will be ready for appending after reading out all the previous records. // The WAL will be ready for appending after reading out all the previous records.
type WAL struct { type WAL struct {
dir string // the living directory of the underlay files dir string // the living directory of the underlay files
md []byte // metadata recorded at the head of each WAL metadata []byte // metadata recorded at the head of each WAL
ri uint64 // index of entry to start reading ri uint64 // index of entry to start reading
decoder *decoder // decoder to decode records decoder *decoder // decoder to decode records
@ -85,7 +86,7 @@ func Create(dirpath string, metadata []byte) (*WAL, error) {
} }
w := &WAL{ w := &WAL{
dir: dirpath, dir: dirpath,
md: metadata, metadata: metadata,
seq: 0, seq: 0,
f: f, f: f,
encoder: newEncoder(f, 0), encoder: newEncoder(f, 0),
@ -208,7 +209,7 @@ func (w *WAL) ReadAll() (metadata []byte, state raftpb.HardState, ents []raftpb.
w.decoder.close() w.decoder.close()
w.ri = 0 w.ri = 0
w.md = metadata w.metadata = metadata
// create encoder (chain crc with the decoder), enable appending // create encoder (chain crc with the decoder), enable appending
w.encoder = newEncoder(w.f, w.decoder.lastCRC()) w.encoder = newEncoder(w.f, w.decoder.lastCRC())
w.decoder = nil w.decoder = nil
@ -234,7 +235,7 @@ func (w *WAL) Cut() error {
if err := w.saveCrc(prevCrc); err != nil { if err := w.saveCrc(prevCrc); err != nil {
return err return err
} }
return w.encoder.encode(&walpb.Record{Type: metadataType, Data: w.md}) return w.encoder.encode(&walpb.Record{Type: metadataType, Data: w.metadata})
} }
func (w *WAL) Sync() error { func (w *WAL) Sync() error {
@ -254,10 +255,7 @@ func (w *WAL) Close() {
} }
func (w *WAL) SaveEntry(e *raftpb.Entry) error { func (w *WAL) SaveEntry(e *raftpb.Entry) error {
b, err := e.Marshal() b := pbutil.MustMarshal(e)
if err != nil {
panic(err)
}
rec := &walpb.Record{Type: entryType, Data: b} rec := &walpb.Record{Type: entryType, Data: b}
if err := w.encoder.encode(rec); err != nil { if err := w.encoder.encode(rec); err != nil {
return err return err
@ -270,10 +268,7 @@ func (w *WAL) SaveState(s *raftpb.HardState) error {
if raft.IsEmptyHardState(*s) { if raft.IsEmptyHardState(*s) {
return nil return nil
} }
b, err := s.Marshal() b := pbutil.MustMarshal(s)
if err != nil {
panic(err)
}
rec := &walpb.Record{Type: stateType, Data: b} rec := &walpb.Record{Type: stateType, Data: b}
return w.encoder.encode(rec) return w.encoder.encode(rec)
} }