mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-09 21:00:58 +00:00
fix(node): stop a departed master's frozen traffic from disabling clients (#6113)
client_global_traffics rows are keyed by (master_guid, email) and are only
ever overwritten by a push from that same master. A master that stops
pushing — decommissioned, reinstalled under a fresh GUID, or detached from
the node — therefore leaves its last snapshot behind permanently.
depletedClientsCond's cross-panel EXISTS branch matched any such row, so a
node kept comparing a client's quota against counters frozen weeks earlier.
Once they exceeded the quota the node disabled the client on every traffic
poll, and the node -> master enable merge latched that off on the master too,
where nothing sets it back. The reported symptom is exactly this: a client at
11 GB of a 24 GB quota, enabled on two nodes, disabled on the third, which
still held a 27-day-old row from a previous master reporting 30 GB.
Bound both the enforcement predicate and the display overlay to rows a master
refreshed within globalTrafficFreshWindow. Masters push every 30s, so a live
master is never affected; a master that is merely unreachable for a while
keeps enforcing for a full day before its numbers are set aside.
The one-way enable merge that makes such a disable permanent on the master is
deliberate (12d84c2a, #4917) and is left alone.
This commit is contained in:
@@ -429,8 +429,7 @@ func (s *ClientService) BulkAdjust(inboundSvc *InboundService, emails []string,
|
||||
}
|
||||
}
|
||||
|
||||
now := time.Now().Unix() * 1000
|
||||
cond := depletedCond(db)
|
||||
cond, condArgs := depletedCond(db)
|
||||
candidateEmails := make([]string, 0, len(plan))
|
||||
for email, entry := range plan {
|
||||
if entry.applyExpiry || entry.applyTotal {
|
||||
@@ -441,7 +440,7 @@ func (s *ClientService) BulkAdjust(inboundSvc *InboundService, emails []string,
|
||||
for _, batch := range chunkStrings(candidateEmails, sqlInChunk) {
|
||||
var rows []string
|
||||
if err := db.Model(xray.ClientTraffic{}).
|
||||
Where(cond+" AND enable = ? AND email IN ?", now, false, batch).
|
||||
Where(cond+" AND enable = ? AND email IN ?", append(append([]any{}, condArgs...), false, batch)...).
|
||||
Pluck("email", &rows).Error; err != nil {
|
||||
return result, needRestart, err
|
||||
}
|
||||
@@ -503,7 +502,7 @@ func (s *ClientService) BulkAdjust(inboundSvc *InboundService, emails []string,
|
||||
for _, batch := range chunkStrings(wasList, sqlInChunk) {
|
||||
var rows []string
|
||||
if err := db.Model(xray.ClientTraffic{}).
|
||||
Where(cond+" AND email IN ?", now, batch).
|
||||
Where(cond+" AND email IN ?", append(append([]any{}, condArgs...), batch)...).
|
||||
Pluck("email", &rows).Error; err != nil {
|
||||
return result, needRestart, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user