增加反链计算按钮

This commit is contained in:
2026-04-09 13:43:58 +08:00
parent f307e30496
commit 351b9d36bb
7 changed files with 127 additions and 13 deletions
+73 -8
View File
@@ -13,6 +13,7 @@ import (
"os" // 文件写入
"path/filepath" // 路径拼接
"strings" // 字符串操作
"sync" // 互斥锁(保护手动触发的并发安全)
"time" // 时间计算(下次运行时间、睡眠)
"sese-engine/storage" // 持久化存储
@@ -22,6 +23,11 @@ import (
type Runner struct {
db *storage.DB
storagePath string // 存储根目录(用于写入 prosper.json
mu sync.Mutex
running bool // 是否正在计算中
nextRun time.Time // 下次计划执行时间
lastRunAt *time.Time // 上次完成时间(nil 表示尚未运行)
lastError string // 上次错误信息(空字符串表示无错误)
}
// New 创建一个 Runner 实例。
@@ -29,6 +35,23 @@ func New(db *storage.DB, storagePath string) *Runner {
return &Runner{db: db, storagePath: storagePath}
}
// Status 返回反链计算器的当前状态快照。
func (r *Runner) Status() map[string]interface{} {
r.mu.Lock()
defer r.mu.Unlock()
m := map[string]interface{}{
"running": r.running,
"next_run": r.nextRun.Format(time.RFC3339),
}
if r.lastRunAt != nil {
m["last_run"] = r.lastRunAt.Format(time.RFC3339)
}
if r.lastError != "" {
m["last_error"] = r.lastError
}
return m
}
// Run 无限循环,每 48 小时执行一次反向链接计算。
// 每次运行对齐到凌晨 2:00(便于在低峰期执行重计算)。
func (r *Runner) Run() {
@@ -39,22 +62,64 @@ func (r *Runner) Run() {
if !target.After(now) {
target = target.Add(48 * time.Hour) // 已过凌晨 2 点,则等明天的 2 点
}
r.mu.Lock()
r.nextRun = target
r.mu.Unlock()
sleep := target.Sub(now)
log.Printf("[backlink] next run at %v (in %v)", target.Format(time.RFC3339), sleep.Round(time.Minute))
time.Sleep(sleep)
log.Printf("[backlink] starting computation at %v", time.Now().Format(time.RFC3339))
if err := r.compute(); err != nil {
log.Printf("[backlink] error: %v", err)
} else {
log.Printf("[backlink] done")
}
r.doCompute()
}
}
// RunNow 立即执行一次计算(用于手动触发或测试)。
// RunNow 立即执行一次计算(用于手动触发)。
// 如果已有计算正在运行则返回 nil(幂等)。
// 执行后重新计算下次自动运行的定时。
func (r *Runner) RunNow() error {
return r.compute()
r.mu.Lock()
if r.running {
r.mu.Unlock()
log.Printf("[backlink] RunNow: already running, skipping")
return nil
}
r.mu.Unlock()
r.doCompute()
return nil
}
// doCompute 执行一次完整的计算,更新状态字段。
func (r *Runner) doCompute() {
r.mu.Lock()
r.running = true
r.lastError = ""
r.mu.Unlock()
log.Printf("[backlink] starting computation at %v", time.Now().Format(time.RFC3339))
err := r.compute()
now := time.Now()
r.mu.Lock()
r.running = false
r.lastRunAt = &now
if err != nil {
r.lastError = err.Error()
}
// 重新计算下次自动运行时间
target := time.Date(now.Year(), now.Month(), now.Day(), 2, 0, 0, 0, now.Location())
if !target.After(now) {
target = target.Add(48 * time.Hour)
}
r.nextRun = target
r.mu.Unlock()
if err != nil {
log.Printf("[backlink] error: %v", err)
} else {
log.Printf("[backlink] done, next run at %v", target.Format(time.RFC3339))
}
}
// ---- 计算核心 ----