@@ -221,7 +221,7 @@ def publish(self, **kwargs):
221221 if settings .CHEF_ENABLED :
222222 controller .update_gitosis .delay (databag ).wait () # @UndefinedVariable
223223
224- def next_container_node (self , formation , container_type ):
224+ def next_container_node (self , formation , container_type , reverse = False ):
225225 count = []
226226 layer = formation .layer_set .get (id = 'runtime' )
227227 runtime_nodes = list (Node .objects .filter (
@@ -237,6 +237,9 @@ def next_container_node(self, formation, container_type):
237237 if not count :
238238 raise ScalingError ('No nodes available for containers' )
239239 count .sort ()
240+ # reverse means order by greatest # of containers, otherwise fewest
241+ if reverse :
242+ count .reverse ()
240243 return count [0 ][1 ]
241244
242245
@@ -280,11 +283,15 @@ def scale_layers(self, **kwargs):
280283 new_nodes = True
281284 # http://docs.celeryproject.org/en/latest/userguide/canvas.html#groups
282285 job = [func () for func in funcs ]
283- # balance containers
284- containers_balanced = self ._balance_containers ()
285286 # launch/terminate nodes in parallel
286287 if job :
287288 group (* job ).apply_async ().join ()
289+ # scale containers in case nodes have been destroyed
290+ runtime_layers = self .layer_set .filter (id = 'runtime' )
291+ if runtime_layers .exists () and runtime_layers [0 ].node_set .count ():
292+ self .scale_containers ()
293+ # balance containers
294+ containers_balanced = self ._balance_containers ()
288295 # once nodes are in place, recalculate the formation and update the data bag
289296 databag = self .calculate ()
290297 # force-converge nodes if there were new nodes or container rebalancing
@@ -316,10 +323,17 @@ def scale_containers(self, **kwargs):
316323 continue
317324 changed = True
318325 while diff < 0 :
319- c = containers .pop (0 )
320- c .delete ()
321- diff = requested - len (containers )
326+ # get the next node with the most containers
327+ node = Formation .objects .next_container_node (self , container_type , reverse = True )
328+ # delete a container attached to that node
329+ for c in containers :
330+ if node == c .node :
331+ containers .remove (c )
332+ c .delete ()
333+ diff += 1
334+ break
322335 while diff > 0 :
336+ # get the next node with the fewest containers
323337 node = Formation .objects .next_container_node (self , container_type )
324338 c = Container .objects .create (owner = self .owner ,
325339 formation = self ,
@@ -328,7 +342,7 @@ def scale_containers(self, **kwargs):
328342 node = node )
329343 containers .append (c )
330344 container_num += 1
331- diff = requested - len ( containers )
345+ diff -= 1
332346 # once nodes are in place, recalculate the formation and update the data bag
333347 databag = self .calculate ()
334348 if changed is True :
0 commit comments