我尝试修改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!!!'
答案 0 :(得分:0)
从pyzmq文档中: https://zeromq.github.io/pyzmq/api/zmq.html#zmq.Socket.send_multipart
msg_parts:iterable
要作为多部分消息发送的一系列对象。每个元素可以是任何可发送对象(帧,字节,缓冲提供者)
消息不会自动分块,您传入的可迭代中的每个元素都是块。因此,您设置它的方式,所有结果数据将是一个块。您需要使用一个迭代器,将结果分块为适当的大小。