@@ -16,6 +16,7 @@ package meta
1616
1717import (
1818 // standard libraries.
19+ "errors"
1920 "time"
2021
2122 // third-party libraries.
@@ -33,6 +34,7 @@ type SyncStore struct {
3334 store
3435
3536 snapshotc chan struct {}
37+ donec chan struct {}
3638}
3739
3840func newSyncStore (wal * walog.WAL , committed * skiplist.SkipList , version , snapshot int64 ) * SyncStore {
@@ -45,15 +47,23 @@ func newSyncStore(wal *walog.WAL, committed *skiplist.SkipList, version, snapsho
4547 marshaler : defaultCodec ,
4648 },
4749 snapshotc : make (chan struct {}, 1 ),
50+ donec : make (chan struct {}),
4851 }
4952
5053 go s .runSnapshot ()
5154
5255 return s
5356}
5457
55- func (s * SyncStore ) Stop () {
56- // TODO(james.yin): stop WAL
58+ func (s * SyncStore ) Close () {
59+ // Close WAL.
60+ s .wal .Close ()
61+ s .wal .Wait ()
62+
63+ // NOTE: Can not close the snapshotc before close the WAL,
64+ // because write to snapshotc in callback of WAL append.
65+ close (s .snapshotc )
66+ <- s .donec
5767}
5868
5969func (s * SyncStore ) Load (key []byte ) (interface {}, bool ) {
@@ -87,27 +97,25 @@ func (s *SyncStore) set(kvs Ranger) error {
8797 }
8898
8999 ch := make (chan error , 1 )
100+ // Use callbacks for ordering guarantees.
90101 s .wal .AppendOne (entry , walog .WithCallback (func (re walog.Result ) {
91102 if re .Err != nil {
92103 ch <- re .Err
93104 return
94105 }
95106
96107 // Update state.
97- func () {
98- s .mu .Lock ()
99- defer s .mu .Unlock ()
100- _ = kvs .Range (func (key []byte , value interface {}) error {
101- if value == deletedMark {
102- s .committed .Remove (key )
103- } else {
104- s .committed .Set (key , value )
105- }
106- return nil
107- })
108-
109- s .version = re .Offset ()
110- }()
108+ s .mu .Lock ()
109+ _ = kvs .Range (func (key []byte , value interface {}) error {
110+ if value == deletedMark {
111+ s .committed .Remove (key )
112+ } else {
113+ s .committed .Set (key , value )
114+ }
115+ return nil
116+ })
117+ s .version = re .Offset ()
118+ s .mu .Unlock ()
111119
112120 close (ch )
113121
@@ -116,12 +124,22 @@ func (s *SyncStore) set(kvs Ranger) error {
116124 default :
117125 }
118126 }))
119- return <- ch
127+ err = <- ch
128+
129+ // Convert ErrClosed.
130+ if err != nil && errors .Is (err , walog .ErrClosed ) {
131+ return ErrClosed
132+ }
133+
134+ return err
120135}
121136
122137func (s * SyncStore ) runSnapshot () {
123138 ticker := time .NewTicker (runSnapshotInterval )
124- defer ticker .Stop ()
139+ defer func () {
140+ ticker .Stop ()
141+ close (s .donec )
142+ }()
125143
126144 for {
127145 select {
@@ -143,7 +161,7 @@ func RecoverSyncStore(walDir string) (*SyncStore, error) {
143161
144162 version := snapshot
145163 wal , err := walog .RecoverWithVisitor (walDir , snapshot , func (data []byte , offset int64 ) error {
146- err2 := defaultCodec .Unmarshl (data , func (key []byte , value interface {}) error {
164+ err2 := defaultCodec .Unmarshal (data , func (key []byte , value interface {}) error {
147165 set (committed , key , value )
148166 return nil
149167 })
0 commit comments