Majordomo asynchronous client API in Python

"""Majordomo Protocol Client API, Python version.

Implements the MDP/Worker spec at

Author: Min RK <moc.liamg|krnimajneb#moc.liamg|krnimajneb>
Based on Java example by Arkadiusz Orzechowski

import logging

import zmq

import MDP
from zhelpers import dump

class MajorDomoClient(object):
"""Majordomo Protocol Client API, Python version.

Implements the MDP/Worker spec at

broker = None
ctx = None
client = None
poller = None
timeout = 2500
verbose = False

def __init__(self, broker, verbose=False): = broker
self.verbose = verbose
self.ctx = zmq.Context()
self.poller = zmq.Poller()
logging.basicConfig(format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S",

def reconnect_to_broker(self):
"""Connect or reconnect to broker"""
if self.client:
self.client = self.ctx.socket(zmq.DEALER)
self.client.linger = 0
self.poller.register(self.client, zmq.POLLIN)
if self.verbose:"I: connecting to broker at %s…",

def send(self, service, request):
"""Send request to broker

if not isinstance(request, list):
request = [request]

# Prefix request with protocol frames
# Frame 0: empty (REQ emulation)
# Frame 1: "MDPCxy" (six bytes, MDP/Client x.y)
# Frame 2: Service name (printable string)

request = ['', MDP.C_CLIENT, service] + request
if self.verbose:
logging.warn("I: send request to '%s' service: ", service)

def recv(self):
"""Returns the reply message or None if there was no reply."""
items = self.poller.poll(self.timeout)
except KeyboardInterrupt:
return # interrupted

if items:
# if we got a reply, process it
msg = self.client.recv_multipart()
if self.verbose:"I: received reply:")

# Don't try to handle errors, just assert noisily
assert len(msg) >= 4

empty = msg.pop(0)
header = msg.pop(0)
assert MDP.C_CLIENT == header

service = msg.pop(0)
return msg
logging.warn("W: permanent error, abandoning request")