Compare commits

..

1 commit

Author SHA1 Message Date
javadtgh
7f3e2828a2
Merge 3b262cf180 into 28a17a80ec 2025-09-28 22:16:43 +03:00

View file

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