Skip to content

Commit 5150a73

Browse files
committed
Fixed #135 -- better container allocation when removing nodes.
1 parent 85afc09 commit 5150a73

1 file changed

Lines changed: 21 additions & 7 deletions

File tree

api/models.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)