def __init__(self): self.threads = {} # { thread number -> 1 } self.queue = Queue() self.thread_mgmt_lock = thread.allocate_lock()
def __init__(self): self.threads = {} # { thread number -> 1 } self.queue = Queue() self.thread_mgmt_lock = threading.Lock()
class ThreadedTaskDispatcher(object): """A Task Dispatcher that creates a thread for each task. """ stop_count = 0 # Number of threads that will stop soon. start_new_thread = thread.start_new_thread logger = logger def __init__(self): self.threads = {} # { thread number -> 1 } self.queue = Queue() self.thread_mgmt_lock = thread.allocate_lock() def handler_thread(self, thread_no): threads = self.threads try: while threads.get(thread_no): task = self.queue.get() if task is None: # Special value: kill this thread. break try: task.service() except Exception as e: self.logger.exception( 'Exception when servicing %r' % task) if isinstance(e, JustTesting): break finally: mlock = self.thread_mgmt_lock mlock.acquire() try: self.stop_count -= 1 threads.pop(thread_no, None) finally: mlock.release() def set_thread_count(self, count): mlock = self.thread_mgmt_lock mlock.acquire() try: threads = self.threads thread_no = 0 running = len(threads) - self.stop_count while running < count: # Start threads. while thread_no in threads: thread_no = thread_no + 1 threads[thread_no] = 1 running += 1 self.start_new_thread(self.handler_thread, (thread_no,)) thread_no = thread_no + 1 if running > count: # Stop threads. to_stop = running - count self.stop_count += to_stop for n in range(to_stop): self.queue.put(None) running -= 1 finally: mlock.release() def add_task(self, task): try: task.defer() self.queue.put(task) except: task.cancel() raise def shutdown(self, cancel_pending=True, timeout=5): self.set_thread_count(0) # Ensure the threads shut down. threads = self.threads expiration = time.time() + timeout while threads: if time.time() >= expiration: self.logger.warning( "%d thread(s) still running" % len(threads)) break time.sleep(0.1) if cancel_pending: # Cancel remaining tasks. try: queue = self.queue while not queue.empty(): task = queue.get() if task is not None: task.cancel() except Empty: # pragma: no cover pass return True return False
class ThreadedTaskDispatcher(object): """A Task Dispatcher that creates a thread for each task. """ stop_count = 0 # Number of threads that will stop soon. logger = logger def __init__(self): self.threads = {} # { thread number -> 1 } self.queue = Queue() self.thread_mgmt_lock = threading.Lock() def start_new_thread(self, target, args): t = threading.Thread(target=target, name='waitress', args=args) t.daemon = True t.start() def handler_thread(self, thread_no): threads = self.threads try: while threads.get(thread_no): task = self.queue.get() if task is None: # Special value: kill this thread. break try: task.service() except Exception as e: self.logger.exception('Exception when servicing %r' % task) if isinstance(e, JustTesting): break finally: with self.thread_mgmt_lock: self.stop_count -= 1 threads.pop(thread_no, None) def set_thread_count(self, count): with self.thread_mgmt_lock: threads = self.threads thread_no = 0 running = len(threads) - self.stop_count while running < count: # Start threads. while thread_no in threads: thread_no = thread_no + 1 threads[thread_no] = 1 running += 1 self.start_new_thread(self.handler_thread, (thread_no, )) thread_no = thread_no + 1 if running > count: # Stop threads. to_stop = running - count self.stop_count += to_stop for n in range(to_stop): self.queue.put(None) running -= 1 def add_task(self, task): try: task.defer() self.queue.put(task) except: task.cancel() raise def shutdown(self, cancel_pending=True, timeout=5): self.set_thread_count(0) # Ensure the threads shut down. threads = self.threads expiration = time.time() + timeout while threads: if time.time() >= expiration: self.logger.warning("%d thread(s) still running" % len(threads)) break time.sleep(0.1) if cancel_pending: # Cancel remaining tasks. try: queue = self.queue while not queue.empty(): task = queue.get() if task is not None: task.cancel() except Empty: # pragma: no cover pass return True return False