@@ -16,7 +16,6 @@ package service
1616
1717import (
1818 "fmt"
19- "strconv"
2019 "strings"
2120
2221 "github.com/haproxytech/client-native/v5/models"
@@ -91,8 +90,6 @@ func (s *Service) updateHAProxySrv(client api.HAProxyClient, srvSlot store.HAPro
9190
9291// scaleHAproxySrvs adds servers to match available addresses
9392func (s * Service ) scaleHAProxySrvs (backend * store.RuntimeBackend ) {
94- var flag bool
95- var disabled []* store.HAProxySrv
9693 var annVal int
9794 var annErr error
9895 // Add disabled HAProxySrvs to match "scale-server-slots"
@@ -108,37 +105,59 @@ func (s *Service) scaleHAProxySrvs(backend *store.RuntimeBackend) {
108105 break
109106 }
110107 }
111- logger .Tracef ("[CONFIG] [BACKEND] [SERVER] backend %s: number of slots %d" , backend .Name , srvSlots )
112- for len (backend .HAProxySrvs ) < srvSlots {
108+ // We expect to have these slots : the already existing ones from backend.HAProxySrvs and the new ones to be added backend.Endpoints.Addresses
109+ // Keep in mind this is about slots not servers. New servers can be already added to backend.HAProxySrvs if the room is sufficient.
110+ // The name backend.Endpoints.Addresses is misleading, it's really about new slots that are parts of new servers and can't have been added directly.
111+ expectedSrvSlots := len (backend .Endpoints .Addresses ) + len (backend .HAProxySrvs )
112+ // We want at least the expected number of slots ...
113+ newSrvSlots := expectedSrvSlots
114+ // ... but if it's not a modulo srvSlots or if it's zero (shouldn't happen) ...
115+ if expectedSrvSlots % srvSlots != 0 || expectedSrvSlots == 0 {
116+ // ... we compute the nearest number of slots greather than expectedSrvSlots and being a modulo of srvSlots
117+ newSrvSlots = expectedSrvSlots - (expectedSrvSlots % srvSlots ) + srvSlots
118+ }
119+
120+ // Get the number of enabled servers in the current list of servers.
121+ enabledSlots := 0
122+ for _ , server := range backend .HAProxySrvs {
123+ if server .Address != "" {
124+ enabledSlots ++
125+ }
126+ }
127+ // If we have to add new slots we'll have to reload, so we can expand the number of free slots by the number srvSlots.
128+ // But we should add any only if there is no room left in the existing list of servers.
129+ if enabledSlots + len (backend .Endpoints .Addresses ) > len (backend .HAProxySrvs ) &&
130+ newSrvSlots - (enabledSlots + len (backend .Endpoints .Addresses )) < srvSlots && newSrvSlots > srvSlots {
131+ newSrvSlots += srvSlots
132+ }
133+
134+ // Create the future slice of slots of the size newSrvSlots ...
135+ slots := make ([]* store.HAProxySrv , newSrvSlots )
136+ // ... copy the existing servers into ...
137+ copy (slots , backend .HAProxySrvs )
138+ i := len (backend .HAProxySrvs )
139+ // ... then add the new slots ...
140+ for addr := range backend .Endpoints .Addresses {
113141 srv := & store.HAProxySrv {
114- Name : fmt .Sprintf ("SRV_%d" , len ( backend . HAProxySrvs ) + 1 ),
115- Address : "" ,
142+ Name : fmt .Sprintf ("SRV_%d" , i + 1 ),
143+ Address : addr ,
116144 Modified : true ,
117145 }
118- backend .HAProxySrvs = append (backend .HAProxySrvs , srv )
119- disabled = append (disabled , srv )
120- flag = true
146+ slots [i ] = srv
147+ i ++
121148 }
122- instance .ReloadIf (flag , "[CONFIG] [BACKEND] [SERVER] Server slots in backend '%s' scaled to match scale-server-slots value: %s" , s .backend .Name , strconv .Itoa (srvSlots ))
123- // Configure remaining addresses in available HAProxySrvs
124- flag = false
125- for addr := range backend .Endpoints .Addresses {
126- if len (disabled ) != 0 {
127- disabled [0 ].Address = addr
128- disabled [0 ].Modified = true
129- disabled = disabled [1 :]
130- } else {
131- srv := & store.HAProxySrv {
132- Name : fmt .Sprintf ("SRV_%d" , len (backend .HAProxySrvs )+ 1 ),
133- Address : addr ,
134- Modified : true ,
135- }
136- backend .HAProxySrvs = append (backend .HAProxySrvs , srv )
137- flag = true
149+ // ... fill in the remaining slots with disabled (empty address) slots.
150+ for j := i ; j < len (slots ); j ++ {
151+ srv := & store.HAProxySrv {
152+ Name : fmt .Sprintf ("SRV_%d" , j + 1 ),
153+ Address : "" ,
154+ Modified : true ,
138155 }
139- delete ( backend . Endpoints . Addresses , addr )
156+ slots [ j ] = srv
140157 }
141- instance .ReloadIf (flag , "[CONFIG] [BACKEND] [SERVER] Server slots in backend '%s' scaled to match available endpoints" , s .backend .Name )
158+ instance .ReloadIf (len (backend .HAProxySrvs ) < len (slots ), "[CONFIG] [BACKEND] [SERVER] Server slots in backend '%s' scaled to match available endpoints" , s .backend .Name )
159+ backend .Endpoints .Addresses = map [string ]struct {}{}
160+ backend .HAProxySrvs = slots
142161}
143162
144163func (s * Service ) getRuntimeBackend (k8s store.K8s ) (backend * store.RuntimeBackend , err error ) {
0 commit comments