Merge pull request #4183 from ryanpetrello/logging-deadlock

don't ship external logs from the main thread of the dispatcher

Reviewed-by: https://github.com/softwarefactory-project-zuul[bot]
This commit is contained in:
softwarefactory-project-zuul[bot]
2019-06-28 16:24:27 +00:00
committed by GitHub
2 changed files with 20 additions and 2 deletions

View File

@@ -10,6 +10,7 @@ from django.core.management.base import BaseCommand
from django.db import connection as django_connection, connections from django.db import connection as django_connection, connections
from kombu import Exchange, Queue from kombu import Exchange, Queue
from awx.main.utils.handlers import AWXProxyHandler
from awx.main.dispatch import get_local_queuename, reaper from awx.main.dispatch import get_local_queuename, reaper
from awx.main.dispatch.control import Control from awx.main.dispatch.control import Control
from awx.main.dispatch.kombu import Connection from awx.main.dispatch.kombu import Connection
@@ -121,6 +122,12 @@ class Command(BaseCommand):
reaper.reap() reaper.reap()
consumer = None consumer = None
# don't ship external logs inside the dispatcher's parent process
# this exists to work around a race condition + deadlock bug on fork
# in cpython itself:
# https://bugs.python.org/issue37429
AWXProxyHandler.disable()
with Connection(settings.BROKER_URL) as conn: with Connection(settings.BROKER_URL) as conn:
try: try:
bcast = 'tower_broadcast_all' bcast = 'tower_broadcast_all'

View File

@@ -6,6 +6,7 @@ import logging
import json import json
import requests import requests
import time import time
import threading
import socket import socket
import select import select
from urllib import parse as urlparse from urllib import parse as urlparse
@@ -286,6 +287,8 @@ class AWXProxyHandler(logging.Handler):
Parameters match same parameters in the actualized handler classes. Parameters match same parameters in the actualized handler classes.
''' '''
thread_local = threading.local()
def __init__(self, **kwargs): def __init__(self, **kwargs):
# TODO: process 'level' kwarg # TODO: process 'level' kwarg
super(AWXProxyHandler, self).__init__(**kwargs) super(AWXProxyHandler, self).__init__(**kwargs)
@@ -322,8 +325,9 @@ class AWXProxyHandler(logging.Handler):
return self._handler return self._handler
def emit(self, record): def emit(self, record):
actual_handler = self.get_handler() if AWXProxyHandler.thread_local.enabled:
return actual_handler.emit(record) actual_handler = self.get_handler()
return actual_handler.emit(record)
def perform_test(self, custom_settings): def perform_test(self, custom_settings):
""" """
@@ -353,6 +357,13 @@ class AWXProxyHandler(logging.Handler):
except RequestException as e: except RequestException as e:
raise LoggingConnectivityException(str(e)) raise LoggingConnectivityException(str(e))
@classmethod
def disable(cls):
cls.thread_local.enabled = False
AWXProxyHandler.thread_local.enabled = True
ColorHandler = logging.StreamHandler ColorHandler = logging.StreamHandler