1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2026-04-08 06:46:07 -04:00

dont start periodic task until necessary

This commit is contained in:
Darien Raymond
2018-08-29 23:00:01 +02:00
parent 5a0a9aa65e
commit eb05a92592
10 changed files with 81 additions and 162 deletions

View File

@@ -11,25 +11,17 @@ type Periodic struct {
Interval time.Duration
// Execute is the task function
Execute func() error
// OnFailure will be called when Execute returns non-nil error
OnError func(error)
access sync.RWMutex
timer *time.Timer
closed bool
}
func (t *Periodic) setClosed(f bool) {
t.access.Lock()
t.closed = f
t.access.Unlock()
access sync.Mutex
timer *time.Timer
running bool
}
func (t *Periodic) hasClosed() bool {
t.access.RLock()
defer t.access.RUnlock()
t.access.Lock()
defer t.access.Unlock()
return t.closed
return !t.running
}
func (t *Periodic) checkedExecute() error {
@@ -38,31 +30,39 @@ func (t *Periodic) checkedExecute() error {
}
if err := t.Execute(); err != nil {
t.access.Lock()
t.running = false
t.access.Unlock()
return err
}
t.access.Lock()
defer t.access.Unlock()
if t.closed {
if !t.running {
return nil
}
t.timer = time.AfterFunc(t.Interval, func() {
if err := t.checkedExecute(); err != nil && t.OnError != nil {
t.OnError(err)
}
t.checkedExecute() // nolint: errcheck
})
return nil
}
// Start implements common.Runnable. Start must not be called multiple times without Close being called.
// Start implements common.Runnable.
func (t *Periodic) Start() error {
t.setClosed(false)
t.access.Lock()
if t.running {
return nil
}
t.running = true
t.access.Unlock()
if err := t.checkedExecute(); err != nil {
t.setClosed(true)
t.access.Lock()
t.running = false
t.access.Unlock()
return err
}
@@ -74,7 +74,7 @@ func (t *Periodic) Close() error {
t.access.Lock()
defer t.access.Unlock()
t.closed = true
t.running = false
if t.timer != nil {
t.timer.Stop()
t.timer = nil

View File

@@ -27,4 +27,10 @@ func TestPeriodicTaskStop(t *testing.T) {
assert(value, Equals, 3)
time.Sleep(time.Second * 4)
assert(value, Equals, 3)
common.Must(task.Start())
time.Sleep(time.Second * 3)
if value != 5 {
t.Fatal("Expected 5, but ", value)
}
common.Must(task.Close())
}