Browse Source

fix: fix delete method (#3569)

Co-authored-by: Пичугин Константин <[email protected]>
konstpic 2 days ago
parent
commit
b65ec83c39
1 changed files with 44 additions and 16 deletions
  1. 44 16
      web/job/ldap_sync_job.go

+ 44 - 16
web/job/ldap_sync_job.go

@@ -214,7 +214,7 @@ func (j *LdapSyncJob) batchSetEnable(ib *model.Inbound, emails []string, enable
         return
     }
 
-    // Подготовка JSON для массового обновления
+    // Prepare JSON for mass update
     clients := make([]model.Client, 0, len(emails))
     for _, email := range emails {
         clients = append(clients, model.Client{
@@ -238,7 +238,7 @@ func (j *LdapSyncJob) batchSetEnable(ib *model.Inbound, emails []string, enable
     j.xrayService.SetToNeedRestart()
 }
 
-// deleteClientsNotInLDAP performs batch deletion of clients not in LDAP
+// deleteClientsNotInLDAP deletes clients not in LDAP using batches and a single restart
 func (j *LdapSyncJob) deleteClientsNotInLDAP(inboundTag string, ldapEmails map[string]struct{}) {
     inbounds, err := j.inboundService.GetAllInbounds()
     if err != nil {
@@ -246,22 +246,24 @@ func (j *LdapSyncJob) deleteClientsNotInLDAP(inboundTag string, ldapEmails map[s
         return
     }
 
+    batchSize := 50 //  clients in 1 batch 
+    restartNeeded := false
+
     for _, ib := range inbounds {
         if ib.Tag != inboundTag {
             continue
         }
         clients, err := j.inboundService.GetClients(ib)
         if err != nil {
+            logger.Warningf("Failed to get clients for inbound %s: %v", ib.Tag, err)
             continue
         }
 
-        // Сбор клиентов для удаления
+        // Collect clients for deletion
         toDelete := []model.Client{}
         for _, c := range clients {
             if _, ok := ldapEmails[c.Email]; !ok {
-                // Use appropriate field depending on protocol
-                client := model.Client{Email: c.Email, ID: c.ID, Password: c.Password}
-                toDelete = append(toDelete, client)
+                toDelete = append(toDelete, c)
             }
         }
 
@@ -269,21 +271,47 @@ func (j *LdapSyncJob) deleteClientsNotInLDAP(inboundTag string, ldapEmails map[s
             continue
         }
 
-        payload := &model.Inbound{
-            Id:       ib.Id,
-            Settings: j.clientsToJSON(toDelete),
-        }
+        // Delete in batches
+        for i := 0; i < len(toDelete); i += batchSize {
+            end := i + batchSize
+            if end > len(toDelete) {
+                end = len(toDelete)
+            }
+            batch := toDelete[i:end]
+
+            for _, c := range batch {
+                var clientKey string
+                switch ib.Protocol {
+                case model.Trojan:
+                    clientKey = c.Password
+                case model.Shadowsocks:
+                    clientKey = c.Email
+                default: // vless/vmess
+                    clientKey = c.ID
+                }
 
-        if _, err := j.inboundService.DelInboundClient(payload.Id, payload.Settings); err != nil {
-            logger.Warningf("Batch delete failed for inbound %s: %v", ib.Tag, err)
-        } else {
-            logger.Infof("Batch deleted %d clients from inbound %s", len(toDelete), ib.Tag)
-            j.xrayService.SetToNeedRestart()
+                if _, err := j.inboundService.DelInboundClient(ib.Id, clientKey); err != nil {
+                    logger.Warningf("Failed to delete client %s from inbound id=%d(tag=%s): %v",
+                        c.Email, ib.Id, ib.Tag, err)
+                } else {
+                    logger.Infof("Deleted client %s from inbound id=%d(tag=%s)",
+                        c.Email, ib.Id, ib.Tag)
+                    // do not restart here
+                    restartNeeded = true
+                }
+            }
         }
     }
+
+    // One time after all batches
+    if restartNeeded {
+        j.xrayService.SetToNeedRestart()
+        logger.Info("Xray restart scheduled after batch deletion")
+    }
 }
 
-// clientsToJSON сериализует массив клиентов в JSON
+
+// clientsToJSON serializes an array of clients to JSON
 func (j *LdapSyncJob) clientsToJSON(clients []model.Client) string {
     b := strings.Builder{}
     b.WriteString("{\"clients\":[")