Skip to content

Commit bbe1e78

Browse files
authored
Merge pull request #11308 from jingyih/wait_purgefile_loop
etcdserver: wait purge file loop to finish during shutdown
2 parents 84e2788 + c447955 commit bbe1e78

File tree

3 files changed

+27
-7
lines changed

3 files changed

+27
-7
lines changed

etcdserver/server.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -807,12 +807,13 @@ func (s *EtcdServer) start() {
807807

808808
func (s *EtcdServer) purgeFile() {
809809
var dberrc, serrc, werrc <-chan error
810+
var dbdonec, sdonec, wdonec <-chan struct{}
810811
if s.Cfg.MaxSnapFiles > 0 {
811-
dberrc = fileutil.PurgeFile(s.getLogger(), s.Cfg.SnapDir(), "snap.db", s.Cfg.MaxSnapFiles, purgeFileInterval, s.done)
812-
serrc = fileutil.PurgeFile(s.getLogger(), s.Cfg.SnapDir(), "snap", s.Cfg.MaxSnapFiles, purgeFileInterval, s.done)
812+
dbdonec, dberrc = fileutil.PurgeFileWithDoneNotify(s.getLogger(), s.Cfg.SnapDir(), "snap.db", s.Cfg.MaxSnapFiles, purgeFileInterval, s.stopping)
813+
sdonec, serrc = fileutil.PurgeFileWithDoneNotify(s.getLogger(), s.Cfg.SnapDir(), "snap", s.Cfg.MaxSnapFiles, purgeFileInterval, s.stopping)
813814
}
814815
if s.Cfg.MaxWALFiles > 0 {
815-
werrc = fileutil.PurgeFile(s.getLogger(), s.Cfg.WALDir(), "wal", s.Cfg.MaxWALFiles, purgeFileInterval, s.done)
816+
wdonec, werrc = fileutil.PurgeFileWithDoneNotify(s.getLogger(), s.Cfg.WALDir(), "wal", s.Cfg.MaxWALFiles, purgeFileInterval, s.stopping)
816817
}
817818

818819
lg := s.getLogger()
@@ -836,6 +837,15 @@ func (s *EtcdServer) purgeFile() {
836837
plog.Fatalf("failed to purge wal file %v", e)
837838
}
838839
case <-s.stopping:
840+
if dbdonec != nil {
841+
<-dbdonec
842+
}
843+
if sdonec != nil {
844+
<-sdonec
845+
}
846+
if wdonec != nil {
847+
<-wdonec
848+
}
839849
return
840850
}
841851
}

pkg/fileutil/purge.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,23 @@ import (
2525
)
2626

2727
func PurgeFile(lg *zap.Logger, dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}) <-chan error {
28-
return purgeFile(lg, dirname, suffix, max, interval, stop, nil)
28+
return purgeFile(lg, dirname, suffix, max, interval, stop, nil, nil)
29+
}
30+
31+
func PurgeFileWithDoneNotify(lg *zap.Logger, dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}) (<-chan struct{}, <-chan error) {
32+
doneC := make(chan struct{})
33+
errC := purgeFile(lg, dirname, suffix, max, interval, stop, nil, doneC)
34+
return doneC, errC
2935
}
3036

3137
// purgeFile is the internal implementation for PurgeFile which can post purged files to purgec if non-nil.
32-
func purgeFile(lg *zap.Logger, dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}, purgec chan<- string) <-chan error {
38+
// if donec is non-nil, the function closes it to notify its exit.
39+
func purgeFile(lg *zap.Logger, dirname string, suffix string, max uint, interval time.Duration, stop <-chan struct{}, purgec chan<- string, donec chan<- struct{}) <-chan error {
3340
errC := make(chan error, 1)
3441
go func() {
42+
if donec != nil {
43+
defer close(donec)
44+
}
3545
for {
3646
fnames, err := ReadDir(dirname)
3747
if err != nil {

pkg/fileutil/purge_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestPurgeFile(t *testing.T) {
4545
stop, purgec := make(chan struct{}), make(chan string, 10)
4646

4747
// keep 3 most recent files
48-
errch := purgeFile(zap.NewExample(), dir, "test", 3, time.Millisecond, stop, purgec)
48+
errch := purgeFile(zap.NewExample(), dir, "test", 3, time.Millisecond, stop, purgec, nil)
4949
select {
5050
case f := <-purgec:
5151
t.Errorf("unexpected purge on %q", f)
@@ -116,7 +116,7 @@ func TestPurgeFileHoldingLockFile(t *testing.T) {
116116
}
117117

118118
stop, purgec := make(chan struct{}), make(chan string, 10)
119-
errch := purgeFile(zap.NewExample(), dir, "test", 3, time.Millisecond, stop, purgec)
119+
errch := purgeFile(zap.NewExample(), dir, "test", 3, time.Millisecond, stop, purgec, nil)
120120

121121
for i := 0; i < 5; i++ {
122122
select {

0 commit comments

Comments
 (0)