def abort_workflow(self, message=None): """Abort workflow - may be called from controller in any state""" logging.getLogger("HWR").info("Aborting workflow: %s", message) logging.getLogger("user_level_log").info("Aborting workflow ...") if self._await_result is not None: # Workflow waiting for answer - send abort self._await_result = [(GphlMessages.BeamlineAbort(), None)] # Shut down hardware object que = self.workflow_queue if que is None: self.workflow_ended() else: # If the queue is running, # workflow_ended will be called from post_execute que.put_nowait(StopIteration)
def workflow_ended(self): if self.get_state() == States.OFF: # No workflow to abort return logging.getLogger("HWR").debug("GPhL workflow ended") self.set_state(States.OFF) if self._await_result is not None: # We are awaiting an answer - give an abort self._await_result.append((GphlMessages.BeamlineAbort(), None)) time.sleep(0.2) elif self._running_process is not None: self._running_process = None # NBNB TODO how do we close down the workflow if there is no answer pending? self._enactment_id = None self._workflow_name = None self.workflow_queue = None self._await_result = None # xx0 = self._running_process # self._running_process = None xx0 = self.collect_emulator_process if xx0 is not None: self.collect_emulator_process = "ABORTED" try: if xx0.poll() is None: xx0.send_signal(signal.SIGINT) time.sleep(3) if xx0.poll() is None: xx0.terminate() time.sleep(9) if xx0.poll() is None: xx0.kill() except Exception: logging.getLogger("HWR").info( "Exception while terminating external workflow process %s", xx0) logging.getLogger("HWR").info("Error was:", exc_info=True)
def processMessage(self, py4j_message): """Receive and process message from workflow server Return goes to server NB Callled freom external java) workflow""" xx0 = self._decode_py4j_message(py4j_message) message_type = xx0.message_type payload = xx0.payload correlation_id = xx0.correlation_id enactment_id = xx0.enactment_id if not enactment_id: logging.getLogger("HWR").error( "GPhL message lacks enactment ID - sending 'Abort' to external workflow" ) return self._response_to_server(GphlMessages.BeamlineAbort(), correlation_id) elif self._enactment_id is None: # NB this should be made less primitive # once we are past direct function calls self._enactment_id = enactment_id elif self._enactment_id != enactment_id: logging.getLogger("HWR").error( "Workflow enactment ID %s != message enactment ID %s" " - sending 'Abort' to external workflow" % (self._enactment_id, enactment_id)) return self._response_to_server(GphlMessages.BeamlineAbort(), correlation_id) elif not payload: logging.getLogger("HWR").error( "GPhL message lacks payload - sending 'Abort' to external workflow" ) return self._response_to_server(GphlMessages.BeamlineAbort(), correlation_id) if message_type in ("SubprocessStarted", "SubprocessStopped"): if self.workflow_queue is not None: # Could happen if we have ended the workflow self.workflow_queue.put_nowait( (message_type, payload, correlation_id, None)) logging.getLogger("HWR").debug( "Subprocess start/stop - return None") return None elif message_type in ( "RequestConfiguration", "GeometricStrategy", "CollectionProposal", "ChooseLattice", "RequestCentring", "ObtainPriorInformation", "PrepareForCentring", ): # Requests: self._await_result = [] self.set_state(States.OPEN) if self.workflow_queue is None: # Could be None if we have ended the workflow return self._response_to_server(GphlMessages.BeamlineAbort(), correlation_id) else: self.workflow_queue.put_nowait( (message_type, payload, correlation_id, self._await_result)) while not self._await_result: time.sleep(0.1) result, correlation_id = self._await_result.pop(0) self._await_result = None if self.get_state() == States.OPEN: self.set_state(States.RUNNING) logging.getLogger("HWR").debug( "GPhL - response=%s jobId=%s messageId=%s" % (result.__class__.__name__, enactment_id, correlation_id)) return self._response_to_server(result, correlation_id) elif message_type in ("WorkflowAborted", "WorkflowCompleted", "WorkflowFailed"): if self.workflow_queue is not None: # Could happen if we have ended the workflow self.workflow_queue.put_nowait( (message_type, payload, correlation_id, None)) self.workflow_queue.put_nowait(StopIteration) logging.getLogger("HWR").debug("Aborting - return None") return None else: logging.getLogger("HWR").error( "GPhL Unknown message type: %s - aborting", message_type) return self._response_to_server(GphlMessages.BeamlineAbort(), correlation_id)