Some checks are pending
Security Checks / security (push) Waiting to run
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
73 lines
1.3 KiB
Go
73 lines
1.3 KiB
Go
package verification
|
|
|
|
import (
|
|
"errors"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
var ErrCleanupAlreadyStarted = errors.New("verification cleanup already started")
|
|
|
|
type CleanupRunner struct {
|
|
store *Store
|
|
mu sync.Mutex
|
|
stop chan struct{}
|
|
done chan struct{}
|
|
stopping bool
|
|
}
|
|
|
|
func NewCleanupRunner(store *Store) *CleanupRunner {
|
|
return &CleanupRunner{store: store}
|
|
}
|
|
|
|
// Start 启动单实例过期清理器;验证码不会从持久化介质恢复。
|
|
func (r *CleanupRunner) Start(interval time.Duration) error {
|
|
if r == nil || r.store == nil || interval <= 0 {
|
|
return ErrInvalidChallenge
|
|
}
|
|
r.mu.Lock()
|
|
if r.stop != nil || r.stopping {
|
|
r.mu.Unlock()
|
|
return ErrCleanupAlreadyStarted
|
|
}
|
|
r.stop = make(chan struct{})
|
|
r.done = make(chan struct{})
|
|
stop, done := r.stop, r.done
|
|
r.mu.Unlock()
|
|
go func() {
|
|
ticker := time.NewTicker(interval)
|
|
defer ticker.Stop()
|
|
defer close(done)
|
|
for {
|
|
select {
|
|
case <-ticker.C:
|
|
r.store.Cleanup()
|
|
case <-stop:
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
return nil
|
|
}
|
|
|
|
func (r *CleanupRunner) Stop() {
|
|
if r == nil {
|
|
return
|
|
}
|
|
r.mu.Lock()
|
|
stop, done := r.stop, r.done
|
|
if stop == nil || r.stopping {
|
|
r.mu.Unlock()
|
|
return
|
|
}
|
|
r.stopping = true
|
|
r.mu.Unlock()
|
|
if stop != nil {
|
|
close(stop)
|
|
<-done
|
|
}
|
|
r.mu.Lock()
|
|
r.stop, r.done, r.stopping = nil, nil, false
|
|
r.mu.Unlock()
|
|
}
|