mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-14 04:56:38 +08:00
feat(nodes): add renewal cycle and auto-advance scheduling (#296)
- Add renewal_cycle field to nodes for tracking paid vs free cycles - Implement auto-advance scheduling when renewal is processed - Add migration test for renewal_cycle column - Update dashboard to show renewal cycle count - Add renewal status display on node detail page
This commit is contained in:
@@ -18,11 +18,12 @@ func (h *Handler) StartBackgroundJobs() {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
h.jobsCancel = cancel
|
||||
h.jobsStarted = true
|
||||
h.jobsWG.Add(2)
|
||||
h.jobsWG.Add(3)
|
||||
h.jobsMu.Unlock()
|
||||
|
||||
go h.runHourlyStatsLoop(ctx)
|
||||
go h.runDailyMaintenanceLoop(ctx)
|
||||
go h.runNodeRenewalCycleLoop(ctx)
|
||||
}
|
||||
|
||||
func (h *Handler) StopBackgroundJobs() {
|
||||
@@ -176,3 +177,39 @@ func (h *Handler) disableExpiredUserTunnels(nowMs int64) {
|
||||
_ = h.repo.DisableUserTunnel(item.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) runNodeRenewalCycleLoop(ctx context.Context) {
|
||||
defer h.jobsWG.Done()
|
||||
|
||||
for {
|
||||
wait := durationUntilNextNodeRenewalCycle(time.Now())
|
||||
timer := time.NewTimer(wait)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if !timer.Stop() {
|
||||
<-timer.C
|
||||
}
|
||||
return
|
||||
case <-timer.C:
|
||||
h.runNodeRenewalCycleJob(time.Now())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func durationUntilNextNodeRenewalCycle(now time.Time) time.Duration {
|
||||
next := now.Truncate(6 * time.Hour).Add(6 * time.Hour)
|
||||
return next.Sub(now)
|
||||
}
|
||||
|
||||
func (h *Handler) runNodeRenewalCycleJob(now time.Time) {
|
||||
if h == nil || h.repo == nil {
|
||||
return
|
||||
}
|
||||
|
||||
advanced, err := h.repo.AdvanceNodeRenewalCycles(now.UnixMilli())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
_ = advanced
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user