perf(clients): batch bulk attach/detach to cut per-item DB work

BulkDetach removed one client per (email x inbound) pair, each with its own
settings rewrite, transaction and full SyncInbound. Add delInboundClients to
remove all targeted clients from an inbound in a single pass and group removals
by inbound, turning O(emails x inbounds) write cycles into O(inbounds).

BulkAttach ran the global getAllEmailSubIDs scan once per target inbound via
checkEmailsExistForClients. Compute that snapshot once per call and thread it
through a new internal addInboundClient; the duplicate check is unaffected
because attach reuses each client's existing identity (same subId).

Covered by bulk_clients_test.go: VLESS round-trip (linkage, settings JSON,
idempotency, record survival), skip-unattached, and Trojan key matching.
This commit is contained in:
MHSanaei
2026-06-02 03:59:10 +02:00
parent d56505004e
commit 4f597a08c4
3 changed files with 443 additions and 15 deletions
+1 -1
View File
@@ -479,7 +479,7 @@ func (s *InboundService) AddInbound(inbound *model.Inbound) (*model.Inbound, boo
if err != nil {
return inbound, false, err
}
existEmail, err := s.clientService.checkEmailsExistForClients(s, clients)
existEmail, err := s.clientService.checkEmailsExistForClients(s, clients, nil)
if err != nil {
return inbound, false, err
}