#NEWLINE# def _handle_next_task( self ) : #NEWLINE# #INDENT# '\n        We have to catch three ways a task can be "done":\n\n        1. normal execution: the task runs/fails and puts a result back on the queue,\n        2. new dependencies: the task yielded new deps that were not complete and\n           will be rescheduled and dependencies added,\n        3. child process dies: we need to catch this separately.\n        ' #NEWLINE# while True : #NEWLINE# #INDENT# self . _purge_children ( ) #NEWLINE# try : #NEWLINE# #INDENT# ( task_id , status , expl , missing , new_requirements ) = self . _task_result_queue . get ( timeout = self . _config . wait_interval ) #NEWLINE# #UNINDENT# except Queue . Empty : #NEWLINE# #INDENT# return #NEWLINE# #UNINDENT# task = self . _scheduled_tasks [ task_id ] #NEWLINE# if ( ( not task ) or ( task_id not in self . _running_tasks ) ) : #NEWLINE# #INDENT# continue #NEWLINE# #UNINDENT# external_task_retryable = ( _is_external ( task ) and self . _config . retry_external_tasks ) #NEWLINE# if ( ( status == FAILED ) and ( not external_task_retryable ) ) : #NEWLINE# #INDENT# self . _email_task_failure ( task , expl ) #NEWLINE# #UNINDENT# new_deps = [ ] #NEWLINE# if new_requirements : #NEWLINE# #INDENT# new_req = [ load_task ( module , name , params ) for ( module , name , params ) in new_requirements ] #NEWLINE# for t in new_req : #NEWLINE# #INDENT# self . add ( t ) #NEWLINE# #UNINDENT# new_deps = [ t . task_id for t in new_req ] #NEWLINE# #UNINDENT# self . _add_task ( worker = self . _id , task_id = task_id , status = status , expl = json . dumps ( expl ) , resources = task . process_resources ( ) , runnable = None , params = task . to_str_params ( ) , family = task . task_family , module = task . task_module , new_deps = new_deps , assistant = self . _assistant ) #NEWLINE# self . _running_tasks . pop ( task_id ) #NEWLINE# if missing : #NEWLINE# #INDENT# reschedule = True #NEWLINE# for task_id in missing : #NEWLINE# #INDENT# self . unfulfilled_counts [ task_id ] += 1 #NEWLINE# if ( self . unfulfilled_counts [ task_id ] > self . _config . max_reschedules ) : #NEWLINE# #INDENT# reschedule = False #NEWLINE# #UNINDENT# #UNINDENT# if reschedule : #NEWLINE# #INDENT# self . add ( task ) #NEWLINE# #UNINDENT# #UNINDENT# self . run_succeeded &= ( ( status == DONE ) or ( len ( new_deps ) > 0 ) ) #NEWLINE# return