瀏覽代碼

Merge pull request #2722 from aanand/fix-scale-race-condition

Fix scale race condition
Aanand Prasad 9 年之前
父節點
當前提交
1e51b7e88b
共有 2 個文件被更改,包括 16 次插入6 次删除
  1. 11 6
      compose/service.py
  2. 5 0
      tests/integration/service_test.py

+ 11 - 6
compose/service.py

@@ -27,9 +27,7 @@ from .const import LABEL_SERVICE
 from .const import LABEL_VERSION
 from .container import Container
 from .parallel import parallel_execute
-from .parallel import parallel_remove
 from .parallel import parallel_start
-from .parallel import parallel_stop
 from .progress_stream import stream_output
 from .progress_stream import StreamOutputError
 from .utils import json_hash
@@ -180,6 +178,10 @@ class Service(object):
             service.start_container(container)
             return container
 
+        def stop_and_remove(container):
+            container.stop(timeout=timeout)
+            container.remove()
+
         running_containers = self.containers(stopped=False)
         num_running = len(running_containers)
 
@@ -225,14 +227,17 @@ class Service(object):
 
         if desired_num < num_running:
             num_to_stop = num_running - desired_num
+
             sorted_running_containers = sorted(
                 running_containers,
                 key=attrgetter('number'))
-            parallel_stop(
-                sorted_running_containers[-num_to_stop:],
-                dict(timeout=timeout))
 
-        parallel_remove(self.containers(stopped=True), {})
+            parallel_execute(
+                sorted_running_containers[-num_to_stop:],
+                stop_and_remove,
+                lambda c: c.name,
+                "Stopping and removing",
+            )
 
     def create_container(self,
                          one_off=False,

+ 5 - 0
tests/integration/service_test.py

@@ -746,6 +746,11 @@ class ServiceTest(DockerClientTestCase):
         for container in containers:
             self.assertEqual(list(container.inspect()['HostConfig']['PortBindings'].keys()), ['8000/tcp'])
 
+    def test_scale_with_immediate_exit(self):
+        service = self.create_service('web', image='busybox', command='true')
+        service.scale(2)
+        assert len(service.containers(stopped=True)) == 2
+
     def test_network_mode_none(self):
         service = self.create_service('web', net=Net('none'))
         container = create_and_start_container(service)