mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-11-02 11:15:03 +03:00
fix(traffic): keep lifecycle statements under SQLite's variable limit
Three statement shapes bound one SQL variable per row and failed past
SQLite's limit, which a node can reach by itself with the clients and
inbounds it reports: the depleted-client lookup and disable in
disableInvalidClients (stopping every expiry and quota check), the
whole-slice Saves of renewed inbounds and traffics (stopping renewals),
and Preload("ClientStats") over all inbounds (stopping config builds).
The IN lists are chunked, the Saves go 100 rows at a time, and client
stats are attached in chunks instead of preloaded.
This commit is contained in:
@@ -105,7 +105,10 @@ func (s *InboundService) disableInvalidClients(tx *gorm.DB, mutationBatch *traff
|
||||
Email string
|
||||
}
|
||||
var targets []target
|
||||
if len(depletedEmails) > 0 {
|
||||
// Chunked like every other statement here: a node alone can report more depleted
|
||||
// clients than SQLite binds variables, which would stop the whole tick.
|
||||
for _, batch := range chunkStrings(depletedEmails, sqlInChunk) {
|
||||
var found []target
|
||||
err = tx.Raw(`
|
||||
SELECT inbounds.id AS inbound_id, inbounds.node_id AS node_id,
|
||||
inbounds.tag AS tag, clients.email AS email
|
||||
@@ -113,10 +116,11 @@ func (s *InboundService) disableInvalidClients(tx *gorm.DB, mutationBatch *traff
|
||||
JOIN client_inbounds ON client_inbounds.client_id = clients.id
|
||||
JOIN inbounds ON inbounds.id = client_inbounds.inbound_id
|
||||
WHERE clients.email IN ?
|
||||
`, depletedEmails).Scan(&targets).Error
|
||||
`, batch).Scan(&found).Error
|
||||
if err != nil {
|
||||
return false, 0, nil, err
|
||||
}
|
||||
targets = append(targets, found...)
|
||||
}
|
||||
|
||||
byInbound := make(map[int][]target)
|
||||
@@ -167,9 +171,9 @@ func (s *InboundService) disableInvalidClients(tx *gorm.DB, mutationBatch *traff
|
||||
count += result.RowsAffected
|
||||
}
|
||||
|
||||
if len(depletedEmails) > 0 {
|
||||
for _, batch := range chunkStrings(depletedEmails, sqlInChunk) {
|
||||
if err := tx.Model(&model.ClientRecord{}).
|
||||
Where("email IN ?", depletedEmails).
|
||||
Where("email IN ?", batch).
|
||||
Updates(map[string]any{"enable": false, "updated_at": now}).Error; err != nil {
|
||||
return false, count, nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user