zmq / zeromq recv_multipart挂起大数据

时间:2015-04-02 11:43:05

标签: python zeromq pyzmq

我尝试修改zeromq example以处理后台任务并使其正常工作。特别是,我有一个xpub / xsub套接字设置,客户端会订阅发布者以接收来自worker的进度更新和结果。

worker_server.py

proxy = zmq.devices.ThreadDevice(zmq.QUEUE, zmq.XSUB, zmq.XPUB)
proxy.bind_in('tcp://127.0.0.1:5002')
proxy.bind_out('tcp://127.0.0.1:5003')
proxy.start()

client.py

ctx = zmq.Context()
socket = server.create_socket(ctx, 'sub')
socket.setsockopt(zmq.SUBSCRIBE, '')
poller = zmq.Poller()
print 'polling'
poller.register(socket, zmq.POLLIN)
ready = dict(poller.poll())
print 'polling done'
if ready and ready.has_key(socket):
    job_id, code, result = socket.recv_multipart()

return {'status': code, 'data': result}

到目前为止,代码适用于小消息,但是当工作者尝试发布大的任务结果(35393030字节)时,客户端不会收到消息并且代码挂起ready = dict(poller.poll())现在,我刚开始学习使用zmq,但是不是send_multipart应该将消息分块?是什么导致客户端无法收到结果

worker.py

def worker(logger_name, method, **task_kwargs):
    job_id = os.getpid()

    ctx = zmq.Context()
    socket = create_socket(ctx, 'pub')
    time.sleep(1)

    logger = logging.getLogger(logger_name)
    logger.setLevel(logging.DEBUG)

    ch = logging.StreamHandler()
    sh = WSLoggingHandler(socket, job_id)
    fh = logging.FileHandler(filename=os.path.join(tmp_folder, 'classifier.log.txt'), encoding='utf-8')

    logger.addHandler(ch)
    logger.addHandler(sh)
    logger.addHandler(fh)

    modules_arr = method.split('.')
    m = __import__(".".join(modules_arr[:-1]), globals(), locals(), -1)
    fn = getattr(m, modules_arr[-1])

    try:
        results = fn(**task_kwargs)
        print 'size of data file %s' %len(results)
        data = [
            str(job_id),
            SUCCESS_CODE,
            results
        ]
        tracker = socket.send_multipart(data)

        print 'sent!!!'
    except Exception, e:
        print traceback.format_exc()
        socket.send_multipart((
            str(job_id),
            ERROR_CODE,
            str(e)
        ))
    finally:
        socket.close()

修改 尝试手动将结果分成较小的块但是避风港已经成功。

    results = fn(**task_kwargs)
    print 'size of data file %s' %len(results)
    data = [
        str(job_id),
        SUCCESS_CODE,
    ] + [results[i: i + 20] for i in xrange(0, len(results), 20)]
    print 'list size %s' %len(data)
    tracker = socket.send_multipart(data)

    print 'sent!!!'

1 个答案:

答案 0 :(得分:0)

从pyzmq文档中: https://zeromq.github.io/pyzmq/api/zmq.html#zmq.Socket.send_multipart

  

msg_parts:iterable

     

要作为多部分消息发送的一系列对象。每个元素可以是任何可发送对象(帧,字节,缓冲提供者)

消息不会自动分块,您传入的可迭代中的每个元素都是块。因此,您设置它的方式,所有结果数据将是一个块。您需要使用一个迭代器,将结果分块为适当的大小。