mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 19:08:58 +00:00
lib/versioner: Convert Staggered to a suture.Service (fixes #3820)
This commit is contained in:
parent
c4ba580cbb
commit
73f9c7d174
@ -33,9 +33,10 @@ type Staggered struct {
|
|||||||
folderPath string
|
folderPath string
|
||||||
interval [4]Interval
|
interval [4]Interval
|
||||||
mutex sync.Mutex
|
mutex sync.Mutex
|
||||||
}
|
|
||||||
|
|
||||||
var testCleanDone chan struct{}
|
stop chan struct{}
|
||||||
|
testCleanDone chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
func NewStaggered(folderID, folderPath string, params map[string]string) Versioner {
|
func NewStaggered(folderID, folderPath string, params map[string]string) Versioner {
|
||||||
maxAge, err := strconv.ParseInt(params["maxAge"], 10, 0)
|
maxAge, err := strconv.ParseInt(params["maxAge"], 10, 0)
|
||||||
@ -57,7 +58,7 @@ func NewStaggered(folderID, folderPath string, params map[string]string) Version
|
|||||||
versionsDir = params["versionsPath"]
|
versionsDir = params["versionsPath"]
|
||||||
}
|
}
|
||||||
|
|
||||||
s := Staggered{
|
s := &Staggered{
|
||||||
versionsPath: versionsDir,
|
versionsPath: versionsDir,
|
||||||
cleanInterval: cleanInterval,
|
cleanInterval: cleanInterval,
|
||||||
folderPath: folderPath,
|
folderPath: folderPath,
|
||||||
@ -68,27 +69,36 @@ func NewStaggered(folderID, folderPath string, params map[string]string) Version
|
|||||||
{604800, maxAge}, // next year -> 1 week between versions
|
{604800, maxAge}, // next year -> 1 week between versions
|
||||||
},
|
},
|
||||||
mutex: sync.NewMutex(),
|
mutex: sync.NewMutex(),
|
||||||
|
stop: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Debugf("instantiated %#v", s)
|
l.Debugf("instantiated %#v", s)
|
||||||
|
|
||||||
go func() {
|
|
||||||
// TODO: This should be converted to a Serve() method.
|
|
||||||
s.clean()
|
|
||||||
if testCleanDone != nil {
|
|
||||||
close(testCleanDone)
|
|
||||||
}
|
|
||||||
tck := time.NewTicker(time.Duration(cleanInterval) * time.Second)
|
|
||||||
defer tck.Stop()
|
|
||||||
for range tck.C {
|
|
||||||
s.clean()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Staggered) clean() {
|
func (v *Staggered) Serve() {
|
||||||
|
v.clean()
|
||||||
|
if v.testCleanDone != nil {
|
||||||
|
close(v.testCleanDone)
|
||||||
|
}
|
||||||
|
|
||||||
|
tck := time.NewTicker(time.Duration(v.cleanInterval) * time.Second)
|
||||||
|
defer tck.Stop()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-tck.C:
|
||||||
|
v.clean()
|
||||||
|
case <-v.stop:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Staggered) Stop() {
|
||||||
|
close(v.stop)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Staggered) clean() {
|
||||||
l.Debugln("Versioner clean: Waiting for lock on", v.versionsPath)
|
l.Debugln("Versioner clean: Waiting for lock on", v.versionsPath)
|
||||||
v.mutex.Lock()
|
v.mutex.Lock()
|
||||||
defer v.mutex.Unlock()
|
defer v.mutex.Unlock()
|
||||||
@ -157,7 +167,7 @@ func (v Staggered) clean() {
|
|||||||
l.Debugln("Cleaner: Finished cleaning", v.versionsPath)
|
l.Debugln("Cleaner: Finished cleaning", v.versionsPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Staggered) expire(versions []string) {
|
func (v *Staggered) expire(versions []string) {
|
||||||
l.Debugln("Versioner: Expiring versions", versions)
|
l.Debugln("Versioner: Expiring versions", versions)
|
||||||
for _, file := range v.toRemove(versions, time.Now()) {
|
for _, file := range v.toRemove(versions, time.Now()) {
|
||||||
if fi, err := osutil.Lstat(file); err != nil {
|
if fi, err := osutil.Lstat(file); err != nil {
|
||||||
@ -174,7 +184,7 @@ func (v Staggered) expire(versions []string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Staggered) toRemove(versions []string, now time.Time) []string {
|
func (v *Staggered) toRemove(versions []string, now time.Time) []string {
|
||||||
var prevAge int64
|
var prevAge int64
|
||||||
firstFile := true
|
firstFile := true
|
||||||
var remove []string
|
var remove []string
|
||||||
@ -226,7 +236,7 @@ func (v Staggered) toRemove(versions []string, now time.Time) []string {
|
|||||||
|
|
||||||
// Archive moves the named file away to a version archive. If this function
|
// Archive moves the named file away to a version archive. If this function
|
||||||
// returns nil, the named file does not exist any more (has been archived).
|
// returns nil, the named file does not exist any more (has been archived).
|
||||||
func (v Staggered) Archive(filePath string) error {
|
func (v *Staggered) Archive(filePath string) error {
|
||||||
l.Debugln("Waiting for lock on ", v.versionsPath)
|
l.Debugln("Waiting for lock on ", v.versionsPath)
|
||||||
v.mutex.Lock()
|
v.mutex.Lock()
|
||||||
defer v.mutex.Unlock()
|
defer v.mutex.Unlock()
|
||||||
|
@ -62,9 +62,12 @@ func TestStaggeredVersioningVersionCount(t *testing.T) {
|
|||||||
os.MkdirAll("testdata/.stversions", 0755)
|
os.MkdirAll("testdata/.stversions", 0755)
|
||||||
defer os.RemoveAll("testdata")
|
defer os.RemoveAll("testdata")
|
||||||
|
|
||||||
testCleanDone = make(chan struct{})
|
v := NewStaggered("", "testdata", map[string]string{"maxAge": strconv.Itoa(365 * 86400)}).(*Staggered)
|
||||||
v := NewStaggered("", "testdata", map[string]string{"maxAge": strconv.Itoa(365 * 86400)}).(Staggered)
|
v.testCleanDone = make(chan struct{})
|
||||||
<-testCleanDone
|
defer v.Stop()
|
||||||
|
go v.Serve()
|
||||||
|
|
||||||
|
<-v.testCleanDone
|
||||||
|
|
||||||
rem := v.toRemove(files, now)
|
rem := v.toRemove(files, now)
|
||||||
if diff, equal := messagediff.PrettyDiff(delete, rem); !equal {
|
if diff, equal := messagediff.PrettyDiff(delete, rem); !equal {
|
||||||
|
Loading…
Reference in New Issue
Block a user