def send_json_rpc(cmd, args, hosts, timeout=0.5): rv = {} context = zmq.Context() if isinstance(hosts, basestring): hosts = [hosts] for host in hosts: rv[host] = None try: request = context.socket(zmq.DEALER) request.connect('tcp://%s:5000' % host) request.setsockopt(zmq.LINGER, 0) #request.send_multipart([msgpack.packb(cmd), msgpack.packb(args)]) request.send(msgpack.packb([cmd, args])) poller = zmq.Poller() poller.register(request, zmq.POLLIN) start = time() while True: socks = dict(poller.poll(timeout=timeout / 10.)) if request in socks and socks[request] == zmq.POLLIN: rv[host] = msgpack.unpackb(request.recv(zmq.POLLERR)) break if (time() - start) > timeout: break sleep(timeout / 10.) except zmq.ZMQError as err: print str(err) continue return rv
def _send_request(req_id, action, key, value=None): """ Generate a request ID, push the request to the node and wait for the result, filtering by the ID on the subscription. This should be a request/response call to the node, but since many must be possible at the same time, a PUSH/PULL AND PUB/SUB with an unique ID for each request is used instead. :return: the node response :rtype: [] """ # Create and connect the sockets. context = current_app.config["context"] subscriber = context.socket(SUB) subscriber.setsockopt_string(SUBSCRIBE, req_id) subscriber.connect(SUB_ENDPOINT) request = context.socket(PUSH) request.setsockopt(SNDTIMEO, _TIMEOUT) request.connect(PUSH_ENDPOINT) # Push the request. request.send_json([req_id, action, key, value]) # Wait for the response from the publisher. poller = Poller() poller.register(subscriber, POLLIN) sockets = dict(poller.poll(_TIMEOUT)) if subscriber not in sockets: # no response, time out raise InternalServerError() # Return the response, without the unique request ID return subscriber.recv_multipart()[1:]