"""Thread for popping Tasks from zmq to Python Queue""" #----------------------------------------------------------------------------- # Copyright (C) 2010-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- import time from threading import Thread try: from queue import Queue except: from Queue import Queue import zmq from zmq.core.poll import _poll as poll from zmq.devices import ThreadDevice from IPython.zmq.parallel import streamsession as ss class QueueStream(object): def __init__(self, in_queue, out_queue): self.in_queue = in_queue self.out_queue = out_queue def send_multipart(self, *args, **kwargs): while self.out_queue.full(): time.sleep(1e-3) self.out_queue.put(('send_multipart', args, kwargs)) def send(self, *args, **kwargs): while self.out_queue.full(): time.sleep(1e-3) self.out_queue.put(('send', args, kwargs)) def recv_multipart(self): return self.in_queue.get() def empty(self): return self.in_queue.empty() class TaskThread(ThreadDevice): """Class for popping Tasks from C-ZMQ->Python Queue""" max_qsize = 100 in_socket = None out_socket = None # queue = None def __init__(self, queue_type, mon_type, engine_id, max_qsize=100): ThreadDevice.__init__(self, 0, queue_type, mon_type) self.session = ss.StreamSession(username='TaskNotifier[%s]'%engine_id) self.engine_id = engine_id self.in_queue = Queue(max_qsize) self.out_queue = Queue(max_qsize) self.max_qsize = max_qsize @property def queues(self): return self.in_queue, self.out_queue @property def can_recv(self): # print self.in_queue.full(), poll((self.queue_socket, zmq.POLLIN),1e-3) return (not self.in_queue.full()) and poll([(self.queue_socket, zmq.POLLIN)], 1e-3 ) @property def can_send(self): return not self.out_queue.empty() def run(self): print 'running' self.queue_socket,self.mon_socket = self._setup_sockets() print 'setup' while True: while not self.can_send and not self.can_recv: # print 'idle' # nothing to do, wait time.sleep(1e-3) while self.can_send: # flush out queue print 'flushing...' meth, args, kwargs = self.out_queue.get() getattr(self.queue_socket, meth)(*args, **kwargs) print 'flushed' if self.can_recv: print 'recving' # get another job from zmq msg = self.queue_socket.recv_multipart(0, copy=False) # put it in the Queue self.in_queue.put(msg) idents,msg = self.session.feed_identities(msg, copy=False) msg = self.session.unpack_message(msg, content=False, copy=False) # notify the Controller that we got it self.mon_socket.send('tracktask', zmq.SNDMORE) header = msg['header'] msg_id = header['msg_id'] content = dict(engine_id=self.engine_id, msg_id = msg_id) self.session.send(self.mon_socket, 'task_receipt', content=content) print 'recvd'