<s> from app . util . log import get_logger <EOL> from app . util . ordered_set_queue import OrderedSetQueue <EOL> from app . util . safe_thread import SafeThread <EOL> from app . master . slave import SlaveMarkedForShutdownError <EOL> class SlaveAllocator ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , build_request_handler ) : <EOL> """<STR_LIT>""" <EOL> self . _logger = get_logger ( __name__ ) <EOL> self . _build_request_handler = build_request_handler <EOL> self . _idle_slaves = OrderedSetQueue ( ) <EOL> self . _allocation_thread = SafeThread ( <EOL> target = self . _slave_allocation_loop , name = '<STR_LIT>' , daemon = True ) <EOL> def start ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . _allocation_thread . is_alive ( ) : <EOL> raise RuntimeError ( '<STR_LIT>' ) <EOL> self . _allocation_thread . start ( ) <EOL> def _slave_allocation_loop ( self ) : <EOL> """<STR_LIT>""" <EOL> while True : <EOL> build_scheduler = self . _build_request_handler . next_prepared_build_scheduler ( ) <EOL> while build_scheduler . needs_more_slaves ( ) : <EOL> claimed_slave = self . _idle_slaves . get ( ) <EOL> if claimed_slave . is_shutdown ( ) or not claimed_slave . is_alive ( use_cached = False ) : <EOL> continue <EOL> if build_scheduler . needs_more_slaves ( ) : <EOL> self . _logger . info ( '<STR_LIT>' , claimed_slave , build_scheduler . build_id ) <EOL> build_scheduler . allocate_slave ( claimed_slave ) <EOL> else : <EOL> self . add_idle_slave ( claimed_slave ) <EOL> self . _logger . info ( '<STR_LIT>' , build_scheduler . build_id ) <EOL> def add_idle_slave ( self , slave ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> slave . mark_as_idle ( ) <EOL> self . _idle_slaves . put ( slave ) <EOL> except SlaveMarkedForShutdownError : <EOL> pass </s>
