Compare commits

..

2 commits

Author SHA1 Message Date
javadtgh
958ea09d50
Merge 3b262cf180 into b65ec83c39 2025-09-29 20:09:29 +03:30
konstpic
b65ec83c39
fix: fix delete method (#3569)
Some checks failed
Release 3X-UI / build (386) (push) Has been cancelled
Release 3X-UI / build (amd64) (push) Has been cancelled
Release 3X-UI / build (arm64) (push) Has been cancelled
Release 3X-UI / build (armv5) (push) Has been cancelled
Release 3X-UI / build (armv6) (push) Has been cancelled
Release 3X-UI / build (armv7) (push) Has been cancelled
Release 3X-UI / build (s390x) (push) Has been cancelled
Release 3X-UI / Build for Windows (push) Has been cancelled
Co-authored-by: Пичугин Константин <k.pichugin@comagic.dev>
2025-09-29 18:16:46 +02:00

View file

@ -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)
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("Batch deleted %d clients from inbound %s", len(toDelete), ib.Tag)
j.xrayService.SetToNeedRestart()
logger.Infof("Deleted client %s from inbound id=%d(tag=%s)",
c.Email, ib.Id, ib.Tag)
// do not restart here
restartNeeded = true
}
}
}
}
// clientsToJSON сериализует массив клиентов в JSON
// One time after all batches
if restartNeeded {
j.xrayService.SetToNeedRestart()
logger.Info("Xray restart scheduled after batch deletion")
}
}
// clientsToJSON serializes an array of clients to JSON
func (j *LdapSyncJob) clientsToJSON(clients []model.Client) string {
b := strings.Builder{}
b.WriteString("{\"clients\":[")