def test_workflow_fast_kill(self): from aiida.cmdline.commands.workflow import Workflow as WfCmd from aiida.orm.backend import construct_backend backend = construct_backend() params = dict() params['nmachine'] = 2 # Create a workflow with 2 subworkflows and start it head_wf = WFTestSimpleWithSubWF() head_wf.start() # Get the user user = backend.users.find(email=self.user_email)[0] wfl = get_workflow_list(user=user) running_no = 0 for w in get_workflow_list(user=user, all_states=True): if w.get_aiida_class().get_state() == wf_states.RUNNING: running_no += 1 self.assertEquals(running_no, 3) # Killing the head workflow wf_cmd = WfCmd() wf_cmd.workflow_kill(*[str(head_wf.pk), '-f', '-q']) # At this point no running workflow should be found running_no = 0 for w in get_workflow_list(user=user, all_states=True): if w.get_aiida_class().get_state() == wf_states.RUNNING: running_no += 1 self.assertEquals(running_no, 0, "No running workflows should be found") self.assertNotEquals(get_all_running_steps(), 0, "At this point there will be running steps.") # Making the daemon to advance. This will automatically set # to FINISHED all the running steps that are (directly) under # a finished workflow legacy_workflow_stepper() self.assertEquals(len(list(get_all_running_steps())), 0, "At this point there should be no running steps.") running_no = 0 for w in get_workflow_list(user=user, all_states=True): if w.get_aiida_class().get_state() == wf_states.RUNNING: running_no += 1 self.assertEquals( running_no, 0, "At this point there should be " "no running workflows.") # Make the daemon to advance a bit more and make sure that no # workflows resurrect. for _ in range(5): legacy_workflow_stepper() self.assertEquals(len(list(get_all_running_steps())), 0, "At this point there should be no running steps.") running_no = 0 for w in get_workflow_list(user=user, all_states=True): if w.get_aiida_class().get_state() == wf_states.RUNNING: running_no += 1 self.assertEquals( running_no, 0, "At this point there should be " "no running workflows.")
def execute_steps(): """ This method loops on the RUNNING workflows and handled the execution of the steps until each workflow reaches an end (or gets stopped for errors). In the loop for each RUNNING workflow the method loops also in each of its RUNNING steps, testing if all the calculation and subworkflows attached to the step are FINISHED. In this case the step is set as FINISHED and the workflow is advanced to the step's next method present in the db with ``advance_workflow``, otherwise if any step's JobCalculation is found in NEW state the method will submit. If none of the previous conditions apply the step is flagged as ERROR and cannot proceed anymore, blocking the future execution of the step and, connected, the workflow. Finally, for each workflow the method tests if there are INITIALIZED steps to be launched, and in case reloads the workflow and execute the specific those steps. In case or error the step is flagged in ERROR state and the stack is reported in the workflow report. """ from aiida.orm import JobCalculation from aiida.orm.implementation import get_all_running_steps logger.info("Querying the worflow DB") running_steps = get_all_running_steps() for s in running_steps: if s.parent.state == wf_states.FINISHED: s.set_state(wf_states.FINISHED) continue w = s.parent.get_aiida_class() logger.info("[{0}] Found active step: {1}".format(w.pk, s.name)) s_calcs_new = [c.pk for c in s.get_calculations() if c._is_new()] s_calcs_finished = [ c.pk for c in s.get_calculations() if c.has_finished_ok() ] s_calcs_failed = [c.pk for c in s.get_calculations() if c.has_failed()] s_calcs_num = len(s.get_calculations()) s_sub_wf_finished = [ sw.pk for sw in s.get_sub_workflows() if sw.has_finished_ok() ] s_sub_wf_failed = [ sw.pk for sw in s.get_sub_workflows() if sw.has_failed() ] s_sub_wf_num = len(s.get_sub_workflows()) if (s_calcs_num == (len(s_calcs_finished) + len(s_calcs_failed)) and s_sub_wf_num == (len(s_sub_wf_finished) + len(s_sub_wf_failed))): logger.info("[{0}] Step: {1} ready to move".format(w.pk, s.name)) s.set_state(wf_states.FINISHED) advance_workflow(w, s) elif len(s_calcs_new) > 0: for pk in s_calcs_new: obj_calc = JobCalculation.get_subclass_from_pk(pk=pk) try: obj_calc.submit() logger.info( "[{0}] Step: {1} launched calculation {2}".format( w.pk, s.name, pk)) except: logger.error( "[{0}] Step: {1} cannot launch calculation {2}".format( w.pk, s.name, pk))