mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-10-13 17:35:02 +03:00
fix(node-sync): keep shared-email lookups on the open transaction
emailUsedByOtherInbounds and emailsUsedByOtherInbounds always queried through database.GetDB(), yet five callers run them inside a transaction: both node traffic sync sweeps (setRemoteTrafficLocked), the inbound edit stats sync (updateClientTraffics) and both email-drop branches of UpdateInboundClient. Each call needed a second pool connection while the transaction held row locks on client_traffics/node_client_traffics. On PostgreSQL, once subscription fetches (UPDATE client_traffics SET last_sub_fetch) blocked on those locks filled the rest of the 25-connection pool, the lookup waited forever, the transaction never ended, and the panel hung until restart. Both helpers now take the *gorm.DB to query on; transactional callers pass tx and the rest pass the pool handle they already hold. The new tests cap the pool at one connection, so any query that escapes the transaction blocks; each went red before the fix on SQLite and (node sync) on a live PostgreSQL 16, and passes after. Closes #6789
This commit is contained in:
@@ -940,7 +940,7 @@ func (s *InboundService) setRemoteTrafficLocked(nodeID int, snap *runtime.Traffi
|
||||
// email's last inbound — wiping it while a sibling still feeds it
|
||||
// loses the summed history, and the next node sync would re-seed the
|
||||
// row with that node's counter alone.
|
||||
sharedEmails, sErr := s.emailsUsedByOtherInbounds(goneEmails, c.Id)
|
||||
sharedEmails, sErr := s.emailsUsedByOtherInbounds(tx, goneEmails, c.Id)
|
||||
if sErr != nil {
|
||||
return false, sErr
|
||||
}
|
||||
@@ -1218,7 +1218,7 @@ func (s *InboundService) setRemoteTrafficLocked(nodeID int, snap *runtime.Traffi
|
||||
}
|
||||
// Same shared-accumulator rule as the inbound-removal sweep above:
|
||||
// keep the row while another inbound still references the email.
|
||||
stillUsed, uErr := s.emailUsedByOtherInbounds(existing.Email, c.Id)
|
||||
stillUsed, uErr := s.emailUsedByOtherInbounds(tx, existing.Email, c.Id)
|
||||
if uErr != nil {
|
||||
return false, uErr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user