2015-07-27 3 views
0

У меня есть класс MyLogger для отправки сообщений на сервер журнала с помощью PUBhandler.zmq PUBhandler не может использоваться в методе __init __()

Исключение возникает, когда получает MyLogger является инстанс в LogWorker.init() метода (как вариант 1), однако, это нормально, если MyLogger является инстанс в LogWorker.log_worker() методе (версия 2).

Любые предложения будут оценены.

import logging 
from multiprocessing import Process 
import os 
import random 
import sys 
import time 

import zmq 
from zmq.log.handlers import PUBHandler 


class MyLogger(object): 
    '''''' 

    def __init__(self, port, handler=None): 
     self.port = port 
     self.handler = handler or self._construct_sock_handler() 
     self.logger = logging.getLogger() 
     self.logger.setLevel(logging.INFO) 
     if not self.logger.handlers: 
      self.logger.addHandler(self.handler) 


    def _construct_sock_handler(self): 
     context = zmq.Context() 
     log_sock = context.socket(zmq.PUB) 
     log_sock.connect("tcp://127.0.0.1:%i" % self.port) 
     time.sleep(0.1) 
     handler = PUBHandler(log_sock) 
     return handler 


    def get_logger(self): 
     return self.logger 


def sub_logger(port, level=logging.DEBUG): 
    ctx = zmq.Context() 
    sub = ctx.socket(zmq.SUB) 
    sub.bind('tcp://127.0.0.1:%i' % port) 
    sub.setsockopt(zmq.SUBSCRIBE, "") 
    logging.basicConfig(level=level) 

    while True: 
     level, message = sub.recv_multipart() 
     if message.endswith('\n'): 
      # trim trailing newline, which will get appended again 
      message = message[:-1] 
     log = getattr(logging, level.lower()) 
     log(message) 


class LogWorker(object): 

    def __init__(self): 
     - pass # version 1 
     + self.logger = MyLogger(port).get_logger() # version 2 

    def log_worker(self, port): 
     - self.logger = MyLogger(port).get_logger() # version 1 
     print "starting logger at %i with level=%s" % (os.getpid(), logging.DEBUG) 

     while True: 
      level = logging.INFO 
      self.logger.log(level, "Hello from %i!" % os.getpid()) 
      time.sleep(1) 

if __name__ == '__main__': 
    if len(sys.argv) > 1: 
     n = int(sys.argv[1]) 
    else: 
     n = 2 

    port = 5555 

    workers = [Process(target=LogWorker().log_worker, args=(port,)) for _ in range(n)] 
    [w.start() for w in workers] 

    try: 
     sub_logger(port) 
    except KeyboardInterrupt: 
     pass 
    finally: 
     [ w.terminate() for w in workers ] 
+0

** ZeroMQ ** архитектура сильно отпугивает от обмена ничего, тем более, никогда не делиться Торцевые экземпляров среди потоков, тем меньше контекста между процессами. Python не является исключением. Рассмотрите все единицы исполнения кода как довольно независимый ** Агент ** и создайте их соответствующие части шаблона формальной структуры связи ZeroMQ Scale независимо друг от друга «внутри» каждого из них. Наслаждайтесь LFJ полномочиями сообщества ZeroMQ & StackOverflow Knowledge Knowledge – user3666197

+0

@ user3666197, спасибо, что вы отредактировали мой вопрос. –

+0

рад, что вам понравилось сообщество StackOverflow. В качестве следующего шага вам может быть интересно прочитать книгу, упомянутую в >>> http://stackoverflow.com/a/25742744/3666197 – user3666197

ответ

0

ответ от владельца pyzmq minrk:

Вы не можете пройти zmq контекстов или сокеты через вилку границы, что происходит, когда вы экземпляр подпроцесса с многопроцессорным. Вы должны убедиться, что вы создали свой Context после того, как вы находитесь в подпроцессе.

решение:

def work(): 
    worker = LogWorker(port) 
    worker.log_worker() 

workers = [ Process(target=work) for _ in range(n) ] 

 Смежные вопросы

  • Нет связанных вопросов^_^