<s> import atexit <EOL> import logging <EOL> import Queue <EOL> import threading <EOL> import traceback <EOL> class WorkerPool ( object ) : <EOL> """<STR_LIT>""" <EOL> _lock = threading . Lock ( ) <EOL> _pool = None <EOL> def __init__ ( self ) : <EOL> self . _idle = [ ] <EOL> self . _workers = { } <EOL> atexit . register ( self . cleanup ) <EOL> @ staticmethod <EOL> def get_instance ( ) : <EOL> """<STR_LIT>""" <EOL> with WorkerPool . _lock : <EOL> if WorkerPool . _pool is None : <EOL> WorkerPool . _pool = WorkerPool ( ) <EOL> return WorkerPool . _pool <EOL> @ staticmethod <EOL> def cleanup ( ) : <EOL> """<STR_LIT>""" <EOL> WorkerPool . get_instance ( ) . _cleanup ( ) <EOL> def _cleanup ( self ) : <EOL> """<STR_LIT>""" <EOL> with self . _lock : <EOL> for queue in self . _workers : <EOL> queue . put ( ( None , None , None , None ) ) <EOL> self . _workers [ queue ] . join ( <NUM_LIT:1> ) <EOL> if self . _workers [ queue ] . is_alive ( ) : <EOL> logging . debug ( '<STR_LIT>' ) <EOL> try : <EOL> self . _idle . remove ( queue ) <EOL> except ValueError : <EOL> pass <EOL> self . _idle = [ ] <EOL> self . _workers = { } <EOL> @ staticmethod <EOL> def get ( one_shot = False ) : <EOL> """<STR_LIT>""" <EOL> return WorkerPool . get_instance ( ) . _get ( one_shot ) <EOL> def _get ( self , one_shot ) : <EOL> """<STR_LIT>""" <EOL> with self . _lock : <EOL> try : <EOL> return self . _idle . pop ( ) <EOL> except IndexError : <EOL> queue = Queue . Queue ( ) <EOL> worker = threading . Thread ( target = self . _service_loop , <EOL> args = ( queue , one_shot ) ) <EOL> worker . daemon = True <EOL> worker . start ( ) <EOL> self . _workers [ queue ] = worker <EOL> return queue <EOL> @ staticmethod <EOL> def release ( queue ) : <EOL> """<STR_LIT>""" <EOL> return WorkerPool . get_instance ( ) . _release ( queue ) <EOL> def _release ( self , queue ) : <EOL> """<STR_LIT>""" <EOL> with self . _lock : <EOL> self . _idle . append ( queue ) <EOL> def _service_loop ( self , request_q , one_shot ) : <EOL> """<STR_LIT>""" <EOL> while True : <EOL> callable , args , kwargs , reply_q = request_q . get ( ) <EOL> if callable is None : <EOL> request_q . task_done ( ) <EOL> return <EOL> exc = None <EOL> trace = None <EOL> retval = None <EOL> try : <EOL> retval = callable ( * args , ** kwargs ) <EOL> except Exception as exc : <EOL> try : <EOL> trace = traceback . format_exc ( ) <EOL> except Exception : <EOL> return <EOL> request_q . task_done ( ) <EOL> if reply_q is not None : <EOL> reply_q . put ( ( request_q , retval , exc , trace ) ) <EOL> if one_shot : <EOL> self . _release ( request_q ) </s>
