mirror of https://github.com/XTLS/Xray-core
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
1.2 KiB
85 lines
1.2 KiB
package task |
|
|
|
import ( |
|
"sync" |
|
"time" |
|
) |
|
|
|
// Periodic is a task that runs periodically. |
|
type Periodic struct { |
|
// Interval of the task being run |
|
Interval time.Duration |
|
// Execute is the task function |
|
Execute func() error |
|
|
|
access sync.Mutex |
|
timer *time.Timer |
|
running bool |
|
} |
|
|
|
func (t *Periodic) hasClosed() bool { |
|
t.access.Lock() |
|
defer t.access.Unlock() |
|
|
|
return !t.running |
|
} |
|
|
|
func (t *Periodic) checkedExecute() error { |
|
if t.hasClosed() { |
|
return nil |
|
} |
|
|
|
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.running { |
|
return nil |
|
} |
|
|
|
t.timer = time.AfterFunc(t.Interval, func() { |
|
t.checkedExecute() |
|
}) |
|
|
|
return nil |
|
} |
|
|
|
// Start implements common.Runnable. |
|
func (t *Periodic) Start() error { |
|
t.access.Lock() |
|
if t.running { |
|
t.access.Unlock() |
|
return nil |
|
} |
|
t.running = true |
|
t.access.Unlock() |
|
|
|
if err := t.checkedExecute(); err != nil { |
|
t.access.Lock() |
|
t.running = false |
|
t.access.Unlock() |
|
return err |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// Close implements common.Closable. |
|
func (t *Periodic) Close() error { |
|
t.access.Lock() |
|
defer t.access.Unlock() |
|
|
|
t.running = false |
|
if t.timer != nil { |
|
t.timer.Stop() |
|
t.timer = nil |
|
} |
|
|
|
return nil |
|
}
|
|
|