浏览代码

Fix race condition on watch_events

Avoid to attach to restarting containers and ignore
race conditions when trying to attach to already
dead containers

Signed-off-by: Ulysses Souza <[email protected]>
Ulysses Souza 6 年之前
父节点
当前提交
47d170b06a
共有 2 个文件被更改,包括 18 次插入1 次删除
  1. 7 1
      compose/cli/log_printer.py
  2. 11 0
      tests/unit/cli/log_printer_test.py

+ 7 - 1
compose/cli/log_printer.py

@@ -230,7 +230,13 @@ def watch_events(thread_map, event_stream, presenters, thread_args):
 
         # Container crashed so we should reattach to it
         if event['id'] in crashed_containers:
-            event['container'].attach_log_stream()
+            container = event['container']
+            if not container.is_restarting:
+                try:
+                    container.attach_log_stream()
+                except APIError:
+                    # Just ignore errors when reattaching to already crashed containers
+                    pass
             crashed_containers.remove(event['id'])
 
         thread_map[event['id']] = build_thread(

+ 11 - 0
tests/unit/cli/log_printer_test.py

@@ -152,6 +152,17 @@ class TestWatchEvents(object):
                 *thread_args)
         assert container_id in thread_map
 
+    def test_container_attach_event(self, thread_map, mock_presenters):
+        container_id = 'abcd'
+        mock_container = mock.Mock(is_restarting=False)
+        mock_container.attach_log_stream.side_effect = APIError("race condition")
+        event_die = {'action': 'die', 'id': container_id}
+        event_start = {'action': 'start', 'id': container_id, 'container': mock_container}
+        event_stream = [event_die, event_start]
+        thread_args = 'foo', 'bar'
+        watch_events(thread_map, event_stream, mock_presenters, thread_args)
+        assert mock_container.attach_log_stream.called
+
     def test_other_event(self, thread_map, mock_presenters):
         container_id = 'abcd'
         event_stream = [{'action': 'create', 'id': container_id}]