Это безопасный/правильный способ сделать на Python LogHandler асинхронный?


Я использую некоторые медленные излучают() методы в Python (2.7) лесозаготовки (электронная почта, HTTP-запрос POST, и т. д.) и с ними происходит синхронно в вызывающем потоке задерживает веб-запросов. Я собрал эту функцию, чтобы взять существующий обработчик и сделать его асинхронным, но я новичок в Python и хочу убедиться, что мои предположения о составе объекта, являются правильными. Вот код:

def patchAsyncEmit(handler):                                                     
    base_emit = handler.emit                                                     
    queue = Queue.Queue()                                                        
    def loop():                                                                  
        while True:                                                              
            record = queue.get(True) # blocks                                    
            try :                                                                
                base_emit(record)                         
            except: # not much you can do when your logger is broken                                                           
                print sys.exc_info()                                      
    thread = threading.Thread(target=loop)                                       
    thread.daemon = True                                                         
    thread.start()                                                               
    def asyncEmit(record):                                                       
        queue.put(record)                                                        
    handler.emit = asyncEmit                                                     
    return handler

Это позволяет мне создать асинхронный LogHandler, используя следующий код:

handler = patchAsyncEmit(logging.handlers.HttpHandler(...))

Я подтверждаю, что сообщения отправляются, а не в вызывающем потоке, но я хочу убедиться, что я получаю только одну очередь и только один поток в обработчике, и что я не в группе риска тех, кто как-то выходят из области видимости.

Я свихнулся или я получил, что хорошо?



Комментарии
1 ответ

Мне представляется, что написание класса будет лучше:

class AsyncHandler(threading.Thread):
def __init__(self, handler):
self._handler = handler
self._queue = Queue.Queue()

self.daemon = True
self.start()

def run(self):
while True:
record = self._queue.get(True)
self._handler.emit(record)

def emit(self, record):
self._queue.put(record)

Ямочный объекты могут быть полезны, но, как правило, яснее создать еще один объект такой.

2
ответ дан 23 сентября 2011 в 03:09 Источник Поделиться