Skip to content

Commit

Permalink
wal: save latest state into new WAL
Browse files Browse the repository at this point in the history
So we could always read out state when open at valid index.
  • Loading branch information
yichengq committed Dec 4, 2014
1 parent 23b32a6 commit af0f34c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
11 changes: 8 additions & 3 deletions wal/wal.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ var (
// A just opened WAL is in read mode, and ready for reading records.
// The WAL will be ready for appending after reading out all the previous records.
type WAL struct {
dir string // the living directory of the underlay files
metadata []byte // metadata recorded at the head of each WAL
dir string // the living directory of the underlay files
metadata []byte // metadata recorded at the head of each WAL
state raftpb.HardState // hardstate recorded at the head of WAL

ri uint64 // index of entry to start reading
decoder *decoder // decoder to decode records
Expand Down Expand Up @@ -236,7 +237,10 @@ func (w *WAL) Cut() error {
if err := w.saveCrc(prevCrc); err != nil {
return err
}
return w.encoder.encode(&walpb.Record{Type: metadataType, Data: w.metadata})
if err := w.encoder.encode(&walpb.Record{Type: metadataType, Data: w.metadata}); err != nil {
return err
}
return w.SaveState(&w.state)
}

func (w *WAL) sync() error {
Expand Down Expand Up @@ -274,6 +278,7 @@ func (w *WAL) SaveState(s *raftpb.HardState) error {
if raft.IsEmptyHardState(*s) {
return nil
}
w.state = *s
b := pbutil.MustMarshal(s)
rec := &walpb.Record{Type: stateType, Data: b}
return w.encoder.encode(rec)
Expand Down
24 changes: 23 additions & 1 deletion wal/wal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,15 @@ func TestCut(t *testing.T) {
if err != nil {
t.Fatal(err)
}
defer w.Close()

// TODO(unihorn): remove this when cut can operate on an empty file
if err := w.SaveEntry(&raftpb.Entry{}); err != nil {
t.Fatal(err)
}
state := raftpb.HardState{Term: 1}
if err := w.SaveState(&state); err != nil {
t.Fatal(err)
}
if err := w.Cut(); err != nil {
t.Fatal(err)
}
Expand All @@ -167,6 +170,25 @@ func TestCut(t *testing.T) {
if g := path.Base(w.f.Name()); g != wname {
t.Errorf("name = %s, want %s", g, wname)
}
w.Close()

// check the state in the last WAL
f, err := os.Open(path.Join(p, wname))
if err != nil {
t.Fatal(err)
}
defer f.Close()
w = &WAL{
decoder: newDecoder(f),
ri: 2,
}
_, gst, _, err := w.ReadAll()
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(gst, state) {
t.Errorf("state = %+v, want %+v", gst, state)
}
}

func TestRecover(t *testing.T) {
Expand Down

0 comments on commit af0f34c

Please sign in to comment.