Example #1
0
    def next(self):
        """ Initiates the start of the next experiment in the queue as long
        as no other experiments are currently running and there is a procedure
        in the queue.
        """
        if self.is_running():
            raise Exception("Another procedure is already running")
        else:
            if self.experiments.has_next():
                log.debug("Manager is initiating the next experiment")
                experiment = self.experiments.next()
                self._running_experiment = experiment

                self._worker = Worker(experiment.results,
                                      port=self.port,
                                      log_level=self.log_level)

                self._monitor = Monitor(self._worker.monitor_queue)
                self._monitor.worker_running.connect(self._running)
                self._monitor.worker_failed.connect(self._failed)
                self._monitor.worker_abort_returned.connect(
                    self._abort_returned)
                self._monitor.worker_finished.connect(self._finish)
                self._monitor.progress.connect(self._update_progress)
                self._monitor.status.connect(self._update_status)
                self._monitor.log.connect(self._update_log)

                self._monitor.start()
                self._worker.start()
Example #2
0
def test_worker_finish():
    procedure = RandomProcedure()
    procedure.iterations = 100
    procedure.delay = 0.001
    file = tempfile.mktemp()
    results = Results(procedure, file)
    worker = Worker(results)
    worker.start()
    worker.join(timeout=5)

    new_results = Results.load(file, procedure_class=RandomProcedure)
    assert new_results.data.shape == (100, 2)
Example #3
0
def test_worker_stop():
    procedure = RandomProcedure()
    file = tempfile.mktemp()
    results = Results(procedure, file)
    worker = Worker(results)
    worker.start()
    worker.stop()
    assert worker.should_stop()
    worker.join()
Example #4
0
def test_worker_stop():
    p = procedure.TestProcedure()
    f = tempfile.mktemp()
    r = Results(p, f)
    w = Worker(r)
    w.start()
    w.stop()
    assert w.should_stop()
    w.join()
Example #5
0
    def next(self):
        """ Initiates the start of the next experiment in the queue as long
        as no other experiments are currently running and there is a procedure
        in the queue.
        """
        if self.is_running():
            raise Exception("Another procedure is already running")
        else:
            if self.experiments.has_next():
                log.debug("Manager is initiating the next experiment")
                experiment = self.experiments.next()
                self._running_experiment = experiment

                self._worker = Worker(experiment.results, port=self.port, log_level=self.log_level)

                self._monitor = Monitor(self._worker.monitor_queue)
                self._monitor.worker_running.connect(self._running)
                self._monitor.worker_failed.connect(self._failed)
                self._monitor.worker_abort_returned.connect(self._abort_returned)
                self._monitor.worker_finished.connect(self._finish)
                self._monitor.progress.connect(self._update_progress)
                self._monitor.status.connect(self._update_status)
                self._monitor.log.connect(self._update_log)

                self._monitor.start()
                self._worker.start()
Example #6
0
def test_worker_stop():
    p = procedure.TestProcedure()
    f = tempfile.mktemp()
    r = Results(p, f)
    w = Worker(r)
    w.start()
    w.stop()
    assert w.should_stop()
    w.join()
Example #7
0
def test_worker_stop():
    procedure = RandomProcedure()
    file = tempfile.mktemp()
    results = Results(procedure, file)
    worker = Worker(results)
    worker.start()
    worker.stop()
    assert worker.should_stop()
    worker.join()
Example #8
0
def test_worker_finish():
    p = procedure.TestProcedure()
    f = tempfile.mktemp()
    r = Results(p, f)
    w = Worker(r)
    w.start()
    w.join()
    sleep(2)
    assert w.is_alive() == False
Example #9
0
def test_zmq_topic_filtering_works(caplog):
    class ThreeEmitsProcedure(Procedure):
        def execute(self):
            self.emit('results', 'Data 1')
            self.emit('progress', 33)
            self.emit('results', 'Data 2')
            self.emit('progress', 66)
            self.emit('results', 'Data 3')
            self.emit('progress', 99)

    procedure = ThreeEmitsProcedure()
    file = tempfile.mktemp()
    results = Results(procedure, file)
    received = []
    worker = Worker(results, port=5888, log_level=logging.DEBUG)
    listener = Listener(port=5888, topic='results', timeout=4.0)
    sleep(
        4.0
    )  # leave time for subscriber and publisher to establish a connection
    worker.start()
    while True:
        if not listener.message_waiting():
            break
        topic, record = listener.receive()
        received.append((topic, record))
    worker.join(timeout=20.0)  # give it enough time to finish the procedure
    assert procedure.status == procedure.FINISHED
    assert len(received) == 3
    assert all([item[0] == 'results' for item in received])
Example #10
0
def test_worker_finish():
    p = procedure.TestProcedure()
    f = tempfile.mktemp()
    r = Results(p, f)
    w = Worker(r)
    w.start()
    w.join()
    sleep(2)
    assert w.is_alive() == False
Example #11
0
def test_worker_finish():
    procedure = RandomProcedure()
    procedure.iterations = 100
    procedure.delay = 0.001
    file = tempfile.mktemp()
    results = Results(procedure, file)
    worker = Worker(results)
    worker.start()
    worker.join(timeout=5)

    assert not worker.is_alive()

    new_results = Results.load(file, procedure_class=RandomProcedure)
    assert new_results.data.shape == (100, 2)
Example #12
0
def test_worker_closes_file_after_finishing():
    procedure = RandomProcedure()
    procedure.iterations = 100
    procedure.delay = 0.001
    file = tempfile.mktemp()
    results = Results(procedure, file)
    worker = Worker(results)
    worker.start()
    worker.join(timeout=5)

    # Test if the file has been properly closed by removing the file
    os.remove(file)
Example #13
0
def test_zmq_does_not_crash_worker(caplog):
    """Check that a ZMQ serialisation usage error does not cause a crash.

    See https://github.com/ralph-group/pymeasure/issues/168
    """
    procedure = RandomProcedure()
    file = tempfile.mktemp()
    results = Results(procedure, file)
    # If we define a port here we get ZMQ communication
    # if cloudpickle is installed
    worker = Worker(results, port=5888, log_level=logging.DEBUG)
    worker.start()
    worker.join(timeout=20.0)  # give it enough time to finish the procedure
    assert procedure.status == procedure.FINISHED
    del worker  # make sure to clean up, reduce the possibility of test
Example #14
0
class Manager(QtCore.QObject):
    """Controls the execution of :class:`.Experiment` classes by implementing
    a queue system in which Experiments are added, removed, executed, or
    aborted. When instantiated, the Manager is linked to a :class:`.Browser`
    and a PyQtGraph `PlotItem` within the user interface, which are updated
    in accordance with the execution status of the Experiments.
    """
    _is_continuous = True
    _start_on_add = True
    queued = QtCore.QSignal(object)
    running = QtCore.QSignal(object)
    finished = QtCore.QSignal(object)
    failed = QtCore.QSignal(object)
    aborted = QtCore.QSignal(object)
    abort_returned = QtCore.QSignal(object)
    log = QtCore.QSignal(object)

    def __init__(self,
                 plot,
                 browser,
                 port=5888,
                 log_level=logging.INFO,
                 parent=None):
        super(Manager, self).__init__(parent=parent)

        self.experiments = ExperimentQueue()
        self._worker = None
        self._running_experiment = None
        self._monitor = None
        self.log_level = log_level

        self.plot = plot
        self.browser = browser

        self.port = port

    def is_running(self):
        """ Returns True if a procedure is currently running
        """
        return self._running_experiment is not None

    def running_experiment(self):
        if self.is_running():
            return self._running_experiment
        else:
            raise Exception("There is no Experiment running")

    def _update_progress(self, progress):
        if self.is_running():
            self._running_experiment.browser_item.setProgress(progress)

    def _update_status(self, status):
        if self.is_running():
            self._running_experiment.procedure.status = status
            self._running_experiment.browser_item.setStatus(status)

    def _update_log(self, record):
        self.log.emit(record)

    def load(self, experiment):
        """ Load a previously executed Experiment
        """
        self.plot.addItem(experiment.curve)
        self.browser.add(experiment)
        self.experiments.append(experiment)

    def queue(self, experiment):
        """ Adds an experiment to the queue.
        """
        self.load(experiment)
        self.queued.emit(experiment)
        if self._start_on_add and not self.is_running():
            self.next()

    def remove(self, experiment):
        """ Removes an Experiment
        """
        self.experiments.remove(experiment)
        self.browser.takeTopLevelItem(
            self.browser.indexOfTopLevelItem(experiment.browser_item))
        self.plot.removeItem(experiment.curve)

    def clear(self):
        """ Remove all Experiments
        """
        for experiment in self.experiments[:]:
            self.remove(experiment)

    def next(self):
        """ Initiates the start of the next experiment in the queue as long
        as no other experiments are currently running and there is a procedure
        in the queue.
        """
        if self.is_running():
            raise Exception("Another procedure is already running")
        else:
            if self.experiments.has_next():
                log.debug("Manager is initiating the next experiment")
                experiment = self.experiments.next()
                self._running_experiment = experiment

                self._worker = Worker(experiment.results,
                                      port=self.port,
                                      log_level=self.log_level)

                self._monitor = Monitor(self._worker.monitor_queue)
                self._monitor.worker_running.connect(self._running)
                self._monitor.worker_failed.connect(self._failed)
                self._monitor.worker_abort_returned.connect(
                    self._abort_returned)
                self._monitor.worker_finished.connect(self._finish)
                self._monitor.progress.connect(self._update_progress)
                self._monitor.status.connect(self._update_status)
                self._monitor.log.connect(self._update_log)

                self._monitor.start()
                self._worker.start()

    def _running(self):
        if self.is_running():
            self.running.emit(self._running_experiment)

    def _clean_up(self):
        self._worker.join()
        del self._worker
        del self._monitor
        self._worker = None
        self._running_experiment = None
        log.debug("Manager has cleaned up after the Worker")

    def _failed(self):
        log.debug("Manager's running experiment has failed")
        experiment = self._running_experiment
        self._clean_up()
        self.failed.emit(experiment)

    def _abort_returned(self):
        log.debug("Manager's running experiment has returned after an abort")
        experiment = self._running_experiment
        self._clean_up()
        self.abort_returned.emit(experiment)

    def _finish(self):
        log.debug("Manager's running experiment has finished")
        experiment = self._running_experiment
        self._clean_up()
        experiment.browser_item.setProgress(100.)
        experiment.curve.update()
        self.finished.emit(experiment)
        if self._is_continuous:  # Continue running procedures
            self.next()

    def resume(self):
        """ Resume processing of the queue.
        """
        self._start_on_add = True
        self._continous = True
        self.next()

    def abort(self):
        """ Aborts the currently running Experiment, but raises an exception if
        there is no running experiment
        """
        if not self.is_running():
            raise Exception("Attempting to abort when no experiment "
                            "is running")
        else:
            self._start_on_add = False
            self._continous = False

            self._worker.stop()

            self.aborted.emit(self._running_experiment)
Example #15
0
class Manager(QtCore.QObject):
    """Controls the execution of :class:`.Experiment` classes by implementing
    a queue system in which Experiments are added, removed, executed, or
    aborted. When instantiated, the Manager is linked to a :class:`.Browser`
    and a PyQtGraph `PlotItem` within the user interface, which are updated
    in accordance with the execution status of the Experiments.
    """

    _is_continuous = True
    _start_on_add = True
    queued = QtCore.QSignal(object)
    running = QtCore.QSignal(object)
    finished = QtCore.QSignal(object)
    failed = QtCore.QSignal(object)
    aborted = QtCore.QSignal(object)
    abort_returned = QtCore.QSignal(object)
    log = QtCore.QSignal(object)

    def __init__(self, plot, browser, port=5888, log_level=logging.INFO, parent=None):
        super(Manager, self).__init__(parent=parent)

        self.experiments = ExperimentQueue()
        self._worker = None
        self._running_experiment = None
        self._monitor = None
        self.log_level = log_level

        self.plot = plot
        self.browser = browser

        self.port = port

    def is_running(self):
        """ Returns True if a procedure is currently running
        """
        return self._running_experiment is not None

    def running_experiment(self):
        if self.is_running():
            return self._running_experiment
        else:
            raise Exception("There is no Experiment running")

    def _update_progress(self, progress):
        if self.is_running():
            self._running_experiment.browser_item.setProgress(progress)

    def _update_status(self, status):
        if self.is_running():
            self._running_experiment.procedure.status = status
            self._running_experiment.browser_item.setStatus(status)

    def _update_log(self, record):
        self.log.emit(record)

    def load(self, experiment):
        """ Load a previously executed Experiment
        """
        self.plot.addItem(experiment.curve)
        self.browser.add(experiment)
        self.experiments.append(experiment)

    def queue(self, experiment):
        """ Adds an experiment to the queue.
        """
        self.load(experiment)
        self.queued.emit(experiment)
        if self._start_on_add and not self.is_running():
            self.next()

    def remove(self, experiment):
        """ Removes an Experiment
        """
        self.experiments.remove(experiment)
        self.browser.takeTopLevelItem(self.browser.indexOfTopLevelItem(experiment.browser_item))
        self.plot.removeItem(experiment.curve)

    def clear(self):
        """ Remove all Experiments
        """
        for experiment in self.experiments[:]:
            self.remove(experiment)

    def next(self):
        """ Initiates the start of the next experiment in the queue as long
        as no other experiments are currently running and there is a procedure
        in the queue.
        """
        if self.is_running():
            raise Exception("Another procedure is already running")
        else:
            if self.experiments.has_next():
                log.debug("Manager is initiating the next experiment")
                experiment = self.experiments.next()
                self._running_experiment = experiment

                self._worker = Worker(experiment.results, port=self.port, log_level=self.log_level)

                self._monitor = Monitor(self._worker.monitor_queue)
                self._monitor.worker_running.connect(self._running)
                self._monitor.worker_failed.connect(self._failed)
                self._monitor.worker_abort_returned.connect(self._abort_returned)
                self._monitor.worker_finished.connect(self._finish)
                self._monitor.progress.connect(self._update_progress)
                self._monitor.status.connect(self._update_status)
                self._monitor.log.connect(self._update_log)

                self._monitor.start()
                self._worker.start()

    def _running(self):
        if self.is_running():
            self.running.emit(self._running_experiment)

    def _clean_up(self):
        self._worker.join()
        del self._worker
        del self._monitor
        self._worker = None
        self._running_experiment = None
        log.debug("Manager has cleaned up after the Worker")

    def _failed(self):
        log.debug("Manager's running experiment has failed")
        experiment = self._running_experiment
        self._clean_up()
        self.failed.emit(experiment)

    def _abort_returned(self):
        log.debug("Manager's running experiment has returned after an abort")
        experiment = self._running_experiment
        self._clean_up()
        self.abort_returned.emit(experiment)

    def _finish(self):
        log.debug("Manager's running experiment has finished")
        experiment = self._running_experiment
        self._clean_up()
        experiment.browser_item.setProgress(100.0)
        experiment.curve.update()
        self.finished.emit(experiment)
        if self._is_continuous:  # Continue running procedures
            self.next()

    def resume(self):
        """ Resume processing of the queue.
        """
        self._start_on_add = True
        self._continous = True
        self.next()

    def abort(self):
        """ Aborts the currently running Experiment, but raises an exception if
        there is no running experiment
        """
        if not self.is_running():
            raise Exception("Attempting to abort when no experiment " "is running")
        else:
            self._start_on_add = False
            self._continous = False

            self._worker.stop()

            self.aborted.emit(self._running_experiment)