Exemple #1
0
    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))
Exemple #2
0
    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")
Exemple #3
0
    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__
Exemple #4
0
    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)
Exemple #5
0
 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)
Exemple #6
0
    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
        )
Exemple #7
0
    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
Exemple #8
0
    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
Exemple #9
0
 def save_instance_state(self, out_state):
     out_state['class_name'] = util.fullname(self)
Exemple #10
0
 def _add_process_info(self, msg, process):
     msg[PROC_INFO_KEY] = {'type': fullname(process)}
Exemple #11
0
 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)
Exemple #12
0
    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))
Exemple #13
0
 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))