def test_class_loader(self): TemplatereplacerProcess = JobProcess.build(TemplatereplacerCalculation) LoadedClass = class_loader.load_class( fullname(TemplatereplacerProcess)) self.assertEqual(TemplatereplacerProcess.__name__, LoadedClass.__name__) self.assertEqual(fullname(TemplatereplacerProcess), fullname(LoadedClass))
def fast_forward(self): if not self.spec().is_deterministic(): raise error.FastForwardError("Cannot fast-forward a process that " "is not deterministic") # kp = knowledge_provider.get_global_provider() kp = None if kp is None: raise error.FastForwardError("Cannot fast-forward because a global" "knowledge provider is not available") # Try and find out if anyone else has had the same inputs try: pids = kp.get_pids_from_classname(util.fullname(self)) except ValueError: pass else: for pid in pids: try: if kp.get_inputs(pid) == self.inputs: for name, value in kp.get_outputs(pid).iteritems(): self.out(name, value) return except ValueError: pass raise error.FastForwardError("Cannot fast forward")
def save_instance_state(self, bundle): """ As the process to save its current instance state. :param bundle: A bundle to save the state to :type bundle: :class:`plum.persistence.Bundle` """ bundle[self.BundleKeys.CLASS_NAME.value] = util.fullname(self) bundle[self.BundleKeys.STATE.value] = self.state bundle[self.BundleKeys.PID.value] = self.pid bundle[self.BundleKeys.FINISHED.value] = self._finished bundle[self.BundleKeys.ABORTED.value] = self._aborted bundle.set_if_not_none(self.BundleKeys.EXCEPTION.value, self._exception) if self._next_transition is not None: bundle[self.BundleKeys.NEXT_TRANSITION.value] = \ self._next_transition.__name__ bundle.set_if_not_none(self.BundleKeys.ABORT_MSG.value, self._abort_msg) # Save inputs and outputs bundle.set_if_not_none(self.BundleKeys.INPUTS.value, self.raw_inputs) bundle[self.BundleKeys.OUTPUTS.value] = Bundle(self._outputs) if self._wait is not None: bundle[self.BundleKeys.WAITING_ON.value] = self.save_wait_on_state() bundle[self.BundleKeys.WAIT_ON_CALLBACK.value] = \ self._wait.callback.__name__
def save_instance_state(self, bundle): """ Ask the process to save its current instance state. :param bundle: A bundle to save the state to :type bundle: :class:`plum.persistence.Bundle` """ # TODO: Add a timeout to this method, the user may not want to wait # indefinitely for the lock with self.__save_lock: # Immutables first bundle[self.BundleKeys.CREATION_TIME.value] = self.creation_time bundle[self.BundleKeys.CLASS_NAME.value] = util.fullname(self) bundle[self.BundleKeys.PID.value] = self.pid # Now state stuff state_bundle = Bundle() self._state.save_instance_state(state_bundle) bundle[self.BundleKeys.STATE.value] = state_bundle bundle[self.BundleKeys.FINISHED.value] = self._finished bundle[self.BundleKeys.TERMINATED.value] = self._terminated # Inputs/outputs bundle.set_if_not_none(self.BundleKeys.INPUTS.value, self.raw_inputs) bundle[self.BundleKeys.OUTPUTS.value] = Bundle(self._outputs)
def on_process_fail(self, process): key = "{}.fail".format(process.pid) exception = process.get_exception() d = {'exception_type': fullname(exception), 'exception_msg': exception.message} self._channel.basic_publish( self._exchange, key, body=self._encode(d)) self.remove_process(process)
def send(self, proc_class, inputs=None): """ Send a Process task to be executed by a runner. :param proc_class: The Process class to run :param inputs: The inputs to supply """ task = {'proc_class': fullname(proc_class), 'inputs': inputs} self._channel.basic_publish( exchange='', routing_key=self._queue, body=self._encode(task), properties=pika.BasicProperties(delivery_mode=2) # Persist )
def save_instance_state(self, out_state): """ Save the current state of this wait on. Subclassing methods should call the superclass method. If a subclassing wait on is unable to save state because, for example, it depends on something that is only available at runtime then it should raise a :class:`Unsupported` error :param out_state: The bundle to save the state into """ out_state[self.CLASS_NAME] = fullname(self) out_state[self.OUTCOME] = self._outcome
def create_from(cls, saved_state, logger=None): """ Create a process from a saved instance state. :param saved_state: The saved state :type saved_state: :class:`plum.persistence.Bundle` :param logger: The logger for this process to use :return: An instance of this process with its state loaded from the save state. """ # Get the class using the class loader and instantiate it class_name = saved_state[Process.BundleKeys.CLASS_NAME.value] my_name = util.fullname(cls) if class_name != my_name: _LOGGER.warning( "Loading class from a bundle that was created from a class with a different " "name. This class is '{}', bundle created by '{}'".format( class_name, my_name)) proc = cls.__new__(cls) proc.load_instance_state(saved_state, logger) return proc
def save_instance_state(self, out_state): out_state['class_name'] = util.fullname(self)
def _add_process_info(self, msg, process): msg[PROC_INFO_KEY] = {'type': fullname(process)}
def on_process_fail(self, process): key = "{}.fail".format(process.pid) exception = process.get_exception() evt_details = {'exception_type': fullname(exception), 'exception_msg': exception.message} self._send_event_msg(process, key, {DETAILS_KEY: evt_details}) self.remove_process(process)
def test_class_loader(self): PwProcess = JobProcess.build(PwCalculation) LoadedClass = class_loader.load_class(fullname(PwProcess)) self.assertEqual(PwProcess.__name__, LoadedClass.__name__) self.assertEqual(fullname(PwProcess), fullname(LoadedClass))
def on_process_start(self, process): key = "{}.start".format(process.pid) d = {'type': fullname(process)} self._channel.basic_publish( self._exchange, key, body=self._encode(d))