def iogate(type, queuein=Queue.Queue(), queueout=Queue.Queue(), network={}): sock = Socket(network['type']) if type == 'in': for port in network['ports']: sock.bind('tcp://0.0.0.0:{port}'.format(port=port)) elif type == 'out': for node in network['nodes']: sock.connect('tcp://{ip}:{port}'.format(ip=node['ip'], port=node['port'])) def receive_messages(): while True: queuein.put({'socket':in_sock, 'data': in_sock.recv()}) print("Message received") def send_messages(): while True: sock.send(queueout.get(block=True)) print("Message has been sent") receiver = threading.Thread(target=receive_messages) sender = threading.Thread(target=send_messages) receiver.start() sender.start() return (queuein, queueout)
def server(url): sock = Socket(PUB) sock.bind(url) channel1 = b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' channel2 = b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' channel3 = b'\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' channel4 = b'\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' doublearray = array.array('d') for i in range(65536): doublearray.insert(i, 0.000001 + i) doublebytes = doublearray.tobytes() # databytes = doublearray.tobytes() # pipes1 = channel1.decode('utf-8') # pipes2 = channel2.decode('utf-8') # pipes3 = channel3.decode('utf-8') # pipes4 = channel4.decode('utf-8') # datas = databytes.decode('utf-8') # pipedatas1 = pipes1+datas # pepedata1 = pipedatas1.encode('utf-8') # pipedatas2 = pipes2+datas # pepedata2 = pipedatas2.encode('utf-8') # pipedatas3 = pipes3+datas # pepedata3 = pipedatas3.encode('utf-8') # pipedatas4 = pipes4+datas # pepedata4 = pipedatas4.encode('utf-8') while True: sock.send(b''.join([channel1, doublebytes])) sock.send(b''.join([channel2, doublebytes])) sock.send(b''.join([channel3, doublebytes])) sock.send(b''.join([channel4, doublebytes]))
def iogate(type, queuein=Queue.Queue(), queueout=Queue.Queue(), network={}): sock = Socket(network['type']) if type == 'in': for port in network['ports']: sock.bind('tcp://0.0.0.0:{port}'.format(port=port)) elif type == 'out': for node in network['nodes']: sock.connect('tcp://{ip}:{port}'.format(ip=node['ip'], port=node['port'])) def receive_messages(): while True: queuein.put({'socket': in_sock, 'data': in_sock.recv()}) print("Message received") def send_messages(): while True: sock.send(queueout.get(block=True)) print("Message has been sent") receiver = threading.Thread(target=receive_messages) sender = threading.Thread(target=send_messages) receiver.start() sender.start() return (queuein, queueout)
def _init_socket(): ''' Initializes nanomsg socket ''' global _socket logger.info("Initializing nanomsg socket for address '%s'...", params.IPC_ADDRESS) # Close socket if necessary try: if _socket: _socket.close() except Exception as e: logger.error("Failed to close nanomsg socket (%s)", e) return # Initialize try: _socket = Socket(PAIR) _socket.bind(params.IPC_ADDRESS) _socket.send_timeout = params.TIMEOUT except Exception as e: logger.error("Failed to init nanomsg socket for address '%s' (%s)", params.IPC_ADDRESS, e) return
def nano_server(endpoint): s = Socket(PAIR) s.bind('ipc://' + endpoint) #s.bind('tcp://127.0.0.1:9001') try: while True: s.recv() s.send('ok') finally: s.close()
def start_service(service_name, service_protocol, service_port): socket = Socket(REP) socket.bind('%s://*:%s' % (service_protocol, service_port)) print 'Starting service %s' % service_name while True: request = socket.recv() print 'Request: %s' % request socket.send('The answer is 42')
def brain_loop(args): sock_node = Socket(BUS) sock_node.bind('tcp://*:%s' % BRAIN_PORT) sock_node.recv_timeout = 250 #sock_node.send_buffer_size = 1000 sock_node.send_timeout = 200 seq = 0 timer = set_mode(args.mode) server = Server(args) while True: ch, value = chanselect([timer.chan, server.chan], []) #print 'AFTER chanselect', ch is timer.chan, time.time() if ch is timer.chan: lights.only(*value) #print "LIGHTS", value try: seq += 1 sock_node.send( '%i %s %s' % (seq, CMD_LIGHTS, ' '.join(lights.rev_lookup[led_pin] for led_pin in value))) except Exception as ex: #print ex pass elif ch is server.chan: if value[0] == 'status': node = None try: seq += 1 sock_node.send('%i PING' % seq) while True: node_msg = sock_node.recv().split() if int(node_msg[0]) == seq: node = 'ok' break elif int(node_msg[0]) > seq: raise Exception('Skipped ping message') except Exception as ex: node = repr(ex) value[1].put({'loop': 'ok', 'node': node}) elif value[0] == 'set_period': timer.period = value[1] elif value[0] == 'trip': timer.trip = True elif value[0] == 'mode': mode = value[1] print("new mode tho %s" % mode) timer = set_mode(mode) else: print "UNKNOWN COMMAND:", value time.sleep(2)
def master_loop(): sock_slave = Socket(PAIR) sock_slave.bind('tcp://*:%s' % MASTER_PORT) sock_slave.recv_timeout = 250 #sock_slave.send_buffer_size = 1000 sock_slave.send_timeout = 200 seq = 0 timer = LightTimer() server = Server() while True: ch, value = chanselect([timer.chan, server.chan], []) #print 'AFTER chanselect', ch is timer.chan, time.time() if ch is timer.chan: lights.only(*value) #print "LIGHTS", value try: seq += 1 sock_slave.send('%i %s %s' % ( seq, CMD_LIGHTS, ' '.join(lights.rev_lookup[led_pin] for led_pin in value))) except Exception as ex: #print ex pass elif ch is server.chan: if value[0] == 'status': slave = None try: seq += 1 sock_slave.send('%i PING' % seq) while True: slave_msg = sock_slave.recv().split() if int(slave_msg[0]) == seq: slave = 'ok' break elif int(slave_msg[0]) > seq: raise Exception('Skipped ping message') except Exception as ex: slave = repr(ex) value[1].put({'loop': 'ok', 'slave': slave}) elif value[0] == 'set_period': timer.period = value[1] elif value[0] == 'trip': timer.trip = True else: print "UNKNOWN COMMAND:", value time.sleep(2)
def receiver(queue, ports, stype=SUB): in_sock = Socket(stype) for port in ports: in_sock.bind('tcp://0.0.0.0:{port}'.format(port=port)) def receive_messages(): while True: queue.put(in_sock.recv()) print("Message received") receiver = threading.Thread(target=receive_messages) receiver.start() return in_sock
class TestGeneralSocketMethods(unittest.TestCase): def setUp(self): self.socket = Socket(PAIR) def tearDown(self): self.socket.close() def test_bind(self): endpoint = self.socket.bind(SOCKET_ADDRESS) self.assertNotEqual(None, endpoint) def test_connect(self): endpoint = self.socket.connect(SOCKET_ADDRESS) self.assertNotEqual(None, endpoint) def test_is_open_is_true_when_open(self): self.assertTrue(self.socket.is_open()) def test_is_open_is_false_when_closed(self): self.socket.close() self.assertFalse(self.socket.is_open()) def test_set_and_get_int_option(self): expected = 500 self.socket.set_int_option(SOL_SOCKET, SNDBUF, expected) actual = self.socket.get_int_option(SOL_SOCKET, SNDBUF) self.assertEqual(expected, actual)
class NanomsgPublisher(HiddenPublisher): """ Publisher class publishing messages to a certain topic to an url Attributes: context (zmq.Context): socket (Socket): Socket object of ZMQ context topic (String): Topic publisher publishs to """ def __init__(self, url, topic): """ Initializes object Args: url (String): url to publish messages to topic (String): Topic to publish messages under """ super(NanomsgPublisher, self).__init__(topic) self._socket = Socket(PUB) self._socket.send_timeout = 1 # Wait 1ms for sending self._socket.bind(url) self._logger = logging.getLogger('NanomsgPublisher') def publish(self, message): """ Publishes message Args: message (String): Message to publish """ self._socket.send('{}|{}'.format(self._topic, message)) def __enter__(self): """ Statement used for the `` with ... as ...:`` returns the object to use in the ``with`` block Returns: NanomsgPublisher """ return self def __exit__(self, exc_type, exc_value, traceback): """ Executed when leaving ``with`` block, regardless whether because of an exception or normal program flow """ self._socket.close()
class ServiceDiscovery(object): def __init__(self, port, deadline=5000): self.socket = Socket(SURVEYOR) self.port = port self.deadline = deadline self.services = defaultdict(set) def bind(self): self.socket.bind('tcp://172.30.42.174:%s' % self.port) self.socket.set_int_option(SURVEYOR, SURVEYOR_DEADLINE, self.deadline) def discover(self): if not self.socket.is_open(): return self.services self.services = defaultdict(set) self.socket.send('service query') while True: try: response = self.socket.recv() except NanoMsgAPIError: break service, address = response.split('|') self.services[service].add(address) return self.services def resolve(self, service): providers = self.services[service] if not providers: return None return random.choice(tuple(providers)) def close(self): self.socket.close()
class ServiceDiscovery(object): def __init__(self, port, deadline=5000): self.socket = Socket(SURVEYOR) self.port = port self.deadline = deadline self.services = defaultdict(set) def bind(self): self.socket.bind('tcp://*:%s' % self.port) self.socket.set_int_option(SURVEYOR, SURVEYOR_DEADLINE, self.deadline) def discover(self): if not self.socket.is_open(): return self.services self.services = defaultdict(set) self.socket.send('service query') while True: try: response = self.socket.recv() except NanoMsgAPIError: break service, address = response.split('|') self.services[service].add(address) return self.services def resolve(self, service): providers = self.services[service] if not providers: return None return random.choice(tuple(providers)) def close(self): self.socket.close()
def nano_sub(bind, tables): """Nanomsg fanout subscriber. (Experimental) This subscriber will use nanomsg to publish the event to outside. """ logger = logging.getLogger("meepo.sub.nano_sub") from nanomsg import Socket, PUB pub_socket = Socket(PUB) pub_socket.bind(bind) def _sub(table): for action in ("write", "update", "delete"): def _sub(pk, action=action): msg = bytes("%s_%s %s" % (table, action, pk), 'utf-8') logger.debug("pub msg %s" % msg) pub_socket.send(msg) signal("%s_%s" % (table, action)).connect(_sub, weak=False) for table in set(tables): _sub(table)
def receiver(queue, addresses, stype): """ Bind a queue to a listening nanomsg socket's multiple endpoints in a separate thread. Parameters ---------- queue : Queue A Queue object to be filled by receiver socket addresses : list A list of strings of format '<protocol>://<ip>:<port>' to bind to stype : int One of the nanomsg scalability socket types: PUSH, PULL, PUB, SUB, PAIR Returns ------- nanomsg socket object """ with err.applicationbound(): in_sock = Socket(stype) for address in addresses: in_sock.bind(address) def receive_messages(): """ """ while True: queue.put(in_sock.recv()) log.info("Message received") receiver = threading.Thread(target=receive_messages) receiver.start() return in_sock
class LogRecorder(object): """ """ def __init__(self, log_file, sub_addr): """ args: ::log_file:: 日志文件名 ::sub_addrs:: 订阅的nanomsg频道列表,暂时先不用,先用内置的列表 """ self.log_file = log_file self.sub_addr = sub_addr def init(self): self.writer = get_writer(self.log_file) self.socket = Socket(SUB) self.socket.set_string_option(SUB, SUB_SUBSCRIBE, "") self.socket.bind(self.sub_addr) def run(self): while True: try: string = self.socket.recv() self.writer.writeline(string) except Exception as e: print e def close(self): self.socket.close() def archive(self, signal_number, stack_frame): self.writer.archive() return None def __del__(self): self.close()
from __future__ import print_function from nanomsg import Socket, PAIR, PUB import time s1 = Socket(PAIR) s1.bind('ipc:///tmp/wand1.ipc') while (True): kkk = "hello world!" print(kkk) s1.send(kkk) time.sleep(1) s1.close()
# vim: set fileencoding=utf-8 from nanomsg import Socket, PAIR URL = "ipc:///tmp/example3" socket = Socket(PAIR) print("Socket created") socket.bind(URL) print("Bound to URL {}".format(URL)) socket.send("Hello world!") print("Message has been sent") socket.close() print("Socket closed")
import time import os, sys from nanomsg import ( PAIR, poll, Socket, NanoMsgAPIError, DONTWAIT ) socket = Socket(PAIR) socket_address = 'ipc:///home/d1plo1d/git_repos/teg/packages/teg-linuxcnc/example_socket' socket.bind(socket_address) # s2.connect(socket_address) # print(s2.recv()) # s2.close() while True: print "SENDING??" try: socket.send(b'hello nanomsg', DONTWAIT) print "SENT!" except NanoMsgAPIError: print "Unable to send nanomsg. Will retry." try: message = socket.recv(flags=DONTWAIT) print("Received request: %s" % message) except NanoMsgAPIError: pass
def run(self, stopflag, q): # signal.signal(signal.SIGINT, signal.SIG_IGN) qO, qN, qD = q print('tcp://*:' + self.port) s1 = Socket(REP) # s1.recv_buffer_size=1024*1024 # s1.reconnect_interval_max=1000 s1.bind('tcp://*:' + self.port) pb_n = args_pb2.p_n() s_n = self.s_n ps_n = s_n * (s_n + 1) pb_n.s_n = s_n # print("nanoMesg up") time.sleep(0.5) running = True pb_sid = args_pb2.p_sid() pb_sid.sid = 0 clients = dict() sys_platform = sys.platform while (running): # print("loop start") if stopflag.value > len(clients.keys()): running = False break if sys_platform == 'win32': try: recvstr = s1.recv() except KeyboardInterrupt: if len(clients.keys()) <= 0: running = False elif stopflag.value >= 0: print("stopflag.value: ", stopflag.value) with stopflag.get_lock(): stopflag.value += 1 continue # os.kill(self.ppid, signal.CTRL_C_EVENT) else: recvstr = s1.recv() # recvstr=s1.recv() # print(ord('c'),ord('p'),ord('r'),ord('k'),"recvstr[0]: ",recvstr[0]) if recvstr[0] == ord('c'): pb_cap = args_pb2.p_cap() pb_cap.ParseFromString(recvstr[1:]) # print("pb_cap.idx",pb_cap.idx) s1.send(pb_n.SerializeToString()) elif recvstr[0] == ord('p'): pb_gpuid = args_pb2.p_str() pb_gpuid.ParseFromString(recvstr[1:]) # TODO 解析 p_str get ohist if pb_gpuid.histNum > 0: # print(list(pb_gpuid.ohist)) qD.put( (pb_gpuid.histNum, self.bestcs, list(pb_gpuid.ohist))) pb_ga = args_pb2.p_ga() pb_ga.start = 0 pb_ga.stop = -1 ii = -1 ind_ = [] try: ii, ind_, self.bestcs = qO.get( False ) #TODO change proto to allow ord('p') fail and retry later. except queue.Empty: if stopflag.value >= 1: print("stopflag.value: ", stopflag.value) pb_ga.idx = -2 stopflag.value += 1 else: pb_ga.idx = -1 s1.send(pb_ga.SerializeToString()) continue # ind_=[random.random()]*(s_n*(s_n+1)) pb_ga.idx = ii pb_ga.bestfv = self.bestcs for i in range(s_n): pb_ga.params.append(ind_[i]) for i in range(s_n * s_n - s_n): pb_ga.params.append(ind_[i + s_n]) for i in range(s_n): pb_ga.params.append(ind_[i + s_n * s_n]) s1.send(pb_ga.SerializeToString()) # clients_lastTimeS[pb_ga.idx]=time.perf_counter() # print("p: ",clients_lastTimeS[pb_ga.idx]) if pb_gpuid.str not in clients: clients[pb_gpuid.str] = gpuClient() print(pb_gpuid.str, " connected.") else: clients[pb_gpuid.str].updateTimeStamp() elif recvstr[0] == ord('r'): res = args_pb2.res() res.ParseFromString(recvstr[1:]) # print("res chi2 recv",res.e, " ridx: ",res.ridx) if stopflag.value >= 1: pb_sid.sid = -1 print("time spend: ", clients.pop(res.idx).runTime) if len(clients.keys()) <= 0: running = False # print("stopflag: ",stopflag.value) # s1.close() s1.send(pb_sid.SerializeToString()) # print("pb_sid send",pb_sid.sid, " ridx: ",res.ridx) if res.idx in clients: clients[res.idx].updateRunTime() #TODO 解析res get shist qN.put((res.ridx, res.e)) if res.hist: # self.counter=self.counter+1 # print(self.counter,self.bestcs) if self.bestcs < 3.2E31: qD.put((-1, self.bestcs, list(res.shist))) elif recvstr[0] == ord('k'): pidx = args_pb2.p_sid() pidx.ParseFromString(recvstr[1:]) # print("keepalive: ",pidx.sid) s1.send('l') else: print("Err recv: ", recvstr[0]) s1.close() qN.close() qD.close() qN.join_thread() qD.join_thread() print("paramsServ done!")
from __future__ import print_function from nanomsg import Socket, PAIR, PUB s1 = Socket(PAIR) s2 = Socket(PAIR) s1.bind('inproc://bob') s2.connect('inproc://bob') s1.send(b'hello nanomsg') print(s2.recv()) s1.close() s2.close() with Socket(PAIR) as s3: with Socket(PAIR) as s4: s3.bind('inproc://demo') s4.connect('inproc://demo') s3.send('hi, I use "with"') print(s4.recv()) s4.send('Ok, I see.') print(s3.recv())
from nanomsg import Socket s1 = Socket('PAIR') s2 = Socket('PAIR') s1.bind('inproc://bob') s2.connect('inproc://bob') s1.send(b'hello nanomsg') print(s2.recv()) s1.close() s2.close()
class PullWorker(threading.Thread): """ End point of pipeline """ def __init__(self, url, event): """ Initializes object Args: url (String): Url to bind to """ super(PullWorker, self).__init__() self._socket = Socket(PULL) self._url = url self._socket.bind(self._url) self._queue = Queue.Queue() self._stop = event def receive(self): """ Reveives message """ raw_msg = self._socket.recv() parsed = {} try: parsed = json.loads(raw_msg) except: logging.exception( 'PullWorker: Received msg could not be JSON parsed %s' % raw_msg) return parsed def run(self): """ Thread run method """ while not self._stop.is_set(): dic = self.receive() self._queue.put(dic) self.__exit__() def next_message(self): """ Return next message of queue Returns: message: Dictionary representing send message """ msg = self._queue.get() self._queue.task_done() return msg def __enter__(self): """ Statement used for the `` with ... as ...:`` returns the object to use in the ``with`` block Returns: PullWorker """ return self def __exit__(self, exc_type, exc_value, traceback): """ Executed when leaving ``with`` block, regardless whether because of an exception or normal program flow """ self._socket.close()
class Daemon(Common): change_funcs = set() bg_tasks = [] def __init__(self, state, logs, worker_class): self.state = state self.logs = logs self.worker_class = worker_class self.sock = Socket(REP) self.sock.bind('inproc://server') self.sock.bind('ipc://socket') self.results = {} self.threads = {} self.running = True self.change_lock = Lock() self.id_gen = iter(range(10000000)).next self.init() def init(self): pass def recv(self): msg = self.sock.recv() #print "Received", self.load(msg) return self.load(msg) def send(self, *args): msg = self.dump(*args) return self.sock.send(msg) def run(self): t = Thread(target=self._bg) t.start() t = Thread(target=self._run) t.start() return t def _bg(self): sock = Socket(REQ) sock.connect('inproc://server') while self.running: for func in self.bg_tasks: msg = self.dump((func, [])) sock.send(msg) self.load(sock.recv()) time.sleep(10) def handle_result(self, id, result): print "Got result id=%r result=%r" % (id, result) self.results[id] = result self.send("ok") def handle_setstate(self, key, value): print "Set state key=%r value=%r" % (key, value) self.state.set(key, value) self.send("ok") def handle_getstate(self, key): value = self.state.get(key) print "Get state key=%r value=%r" % (key, value) self.send(value) def handle_out(self, id, txt): print "Got %s id=%r result=%r" % ('out', id, txt) self.logs.append(id, 'out', txt) self.send("ok") def handle_err(self, id, txt): print "Got %s id=%r result=%r" % ('err', id, txt) self.logs.append(id, 'err', txt) self.send("ok") def handle_getresult(self, id): result = self.results.get(id) if result: del self.results[id] del self.threads[id] print "sending result=%r for id=%r" % (result, id) self.send(result) def handle_getlog(self, id, since): result = self.logs.get(id, since) print "sending log=%r for id=%r" % (result, id) self.send(result) def _run(self): while self.running: (cmd, args) = self.recv() func = getattr(self, 'handle_' + cmd, None) if func: func(*args) continue t_id, t = self.spawn_worker(cmd, args) self.send(t_id) self.threads[t_id] = t print "started thread for id=%r func=%r args=%r" % (t_id, func, args) def spawn_worker(self, cmd, args): t_id = self.id_gen() target = lambda: self.wrap(t_id, cmd, args) t = Thread(target=target) t.start() return t_id, t def wrap(self, id, cmd, args): if cmd in self.change_funcs: self.change_lock.acquire() try: w = self.worker_class(id) func = getattr(w, cmd, w.noop) if hasattr(func, 'api_exposed'): try: res = func(*args) except Exception, e: res = repr(e) else:
from nanomsg import poll, Socket, PUSH, PULL, DONTWAIT import argparse import subprocess from time import sleep parser = argparse.ArgumentParser( description='Extract parameters from command-line') parser.add_argument('-cc', '--clientcount', default='1') parser.add_argument('-mc', '--messagecount', default='1000') args = parser.parse_args() client_count = int(args.clientcount) message_count = int(args.messagecount) server_sock = Socket(PUSH) server_sock.bind('ipc://nanopushpull.bin') client_proc_list = [] for i in range(client_count): client_proc_list.append( subprocess.Popen(['python', 'nanopullclnt.py', '-cn', str(i + 1)])) # Give client processes time to start, otherwise the ones starting first will # get hit with a big chunk of the messages (which may not be a bad thing) sleep(1) for n in range(message_count): sent = False while not sent: try: server_sock.send(b'msg %d' % (n), DONTWAIT)
class Daemon(Common): change_funcs = set() bg_tasks = [] def __init__(self, state, logs, worker_class): self.state = state self.logs = logs self.worker_class = worker_class self.sock = Socket(REP) self.sock.bind("inproc://server") self.sock.bind("ipc://socket") self.results = {} self.threads = {} self.running = True self.change_lock = Lock() self.id_gen = iter(range(10000000)).next self.init() def init(self): pass def recv(self): msg = self.sock.recv() # print "Received", self.load(msg) return self.load(msg) def send(self, *args): msg = self.dump(*args) return self.sock.send(msg) def run(self): t = Thread(target=self._bg) t.start() t = Thread(target=self._run) t.start() return t def _bg(self): sock = Socket(REQ) sock.connect("inproc://server") while self.running: for func in self.bg_tasks: msg = self.dump((func, [])) sock.send(msg) self.load(sock.recv()) time.sleep(10) def handle_result(self, id, result): print "Got result id=%r result=%r" % (id, result) self.results[id] = result self.send("ok") def handle_setstate(self, key, value): print "Set state key=%r value=%r" % (key, value) self.state.set(key, value) self.send("ok") def handle_getstate(self, key): value = self.state.get(key) print "Get state key=%r value=%r" % (key, value) self.send(value) def handle_out(self, id, txt): print "Got %s id=%r result=%r" % ("out", id, txt) self.logs.append(id, "out", txt) self.send("ok") def handle_err(self, id, txt): print "Got %s id=%r result=%r" % ("err", id, txt) self.logs.append(id, "err", txt) self.send("ok") def handle_getresult(self, id): result = self.results.get(id) if result: del self.results[id] del self.threads[id] print "sending result=%r for id=%r" % (result, id) self.send(result) def handle_getlog(self, id, since): result = self.logs.get(id, since) print "sending log=%r for id=%r" % (result, id) self.send(result) def _run(self): while self.running: (cmd, args) = self.recv() func = getattr(self, "handle_" + cmd, None) if func: func(*args) continue t_id, t = self.spawn_worker(cmd, args) self.send(t_id) self.threads[t_id] = t print "started thread for id=%r func=%r args=%r" % (t_id, func, args) def spawn_worker(self, cmd, args): t_id = self.id_gen() target = lambda: self.wrap(t_id, cmd, args) t = Thread(target=target) t.start() return t_id, t def wrap(self, id, cmd, args): if cmd in self.change_funcs: self.change_lock.acquire() try: w = self.worker_class(id) func = getattr(w, cmd, w.noop) if hasattr(func, "api_exposed"): try: res = func(*args) except Exception, e: res = repr(e) else: