perf(traffic): skip unchanged global writes between heartbeats (#6931)

* perf(traffic): skip unchanged global writes between heartbeats

Persist directional usage changes immediately, including lower resets, while
refreshing identical global totals only at an inclusive one-hour heartbeat.
Use the GORM clock consistently for the existing 24-hour freshness window and
preserve local-only snapshots, quota enforcement, and downstream forwarding.

Fixes #6928

* docs(traffic): describe persisted global heartbeat timestamps

Replace the stale every-push model comment with the change-or-hourly-heartbeat
rule. Keep the local-counter separation, delta accounting, MAX fold and reset
semantics explicit without treating UpdatedAt as a last-push timestamp.

Address the nonblocking review feedback on PR #6931 without rewriting
published history.

Refs #6928
This commit is contained in:
Hamed
2026-10-25 11:14:05 +03:30
committed by GitHub
parent 73fad424ed
commit 64a7697f56
10 changed files with 699 additions and 38 deletions
+11
View File
@@ -386,6 +386,17 @@ A client reset is queued per hosting node in `model.NodePendingReset` (`service/
and replayed by the node sync until the node accepts it.
Periodic resets: `job/periodic_traffic_reset_job.go` (keyed off `Inbound.TrafficReset`).
Cross-panel totals are stored per master GUID and hosted email, separately from local
`client_traffics`. Directional counter changes, including lower values and resets, persist
on the next push. Identical totals refresh only when the persisted timestamp is at least
one hour old; pushes still send the same batches. Display and quota reads retain the
inclusive 24-hour persisted-row freshness window. Full-list snapshots remain local-only,
while slim/detail reads and downstream forwarding retain their global overlays.
The heartbeat coarsens liveness, not counter propagation: an idle master can expire up to
one hour earlier relative to its final unchanged push. Active hourly refresh leaves roughly
23 hours of missed-push margin. No cache, external service or configurable interval is added.
### 5.4 Background jobs (cron)
All registered in `web.go` → `startTask()`. Each is a struct with a `Run()` method in `internal/web/job/`: