From 625b03fae3ccb0b9923a2b69b211af96e2a6b56f Mon Sep 17 00:00:00 2001 From: jtc42 Date: Fri, 1 Nov 2019 18:10:04 +0000 Subject: [PATCH] Moved lock submodule into 'common' and updated docs --- docs/source/common.rst | 12 ++++++++++++ docs/source/index.rst | 1 + docs/source/plugins/class.rst | 9 --------- docs/source/plugins/example/plugin.py | 6 +++--- docs/source/plugins/hardware.rst | 16 ++++++---------- openflexure_microscope/__init__.py | 2 +- openflexure_microscope/camera/base.py | 4 ++-- openflexure_microscope/{ => common}/lock.py | 2 +- openflexure_microscope/microscope.py | 15 +++++++-------- openflexure_microscope/stage/base.py | 4 ++-- 10 files changed, 35 insertions(+), 36 deletions(-) create mode 100644 docs/source/common.rst rename openflexure_microscope/{ => common}/lock.py (98%) diff --git a/docs/source/common.rst b/docs/source/common.rst new file mode 100644 index 00000000..8de93d44 --- /dev/null +++ b/docs/source/common.rst @@ -0,0 +1,12 @@ +Common utilities +======================================================= + +Tasks module +------------ +.. automodule:: openflexure_microscope.common.tasks + :members: + +Lock module +----------- +.. automodule:: openflexure_microscope.common.lock + :members: \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 28ef7180..da09da0a 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -9,6 +9,7 @@ Welcome to OpenFlexure Microscope Software's documentation! config.rst microscope.rst camera.rst + common.rst plugins.rst api.rst diff --git a/docs/source/plugins/class.rst b/docs/source/plugins/class.rst index 205a7071..6e0fb3e3 100644 --- a/docs/source/plugins/class.rst +++ b/docs/source/plugins/class.rst @@ -9,15 +9,6 @@ Plugin class .. autoclass:: openflexure_microscope.api.v1.views.MicroscopeViewPlugin :members: -Task module ------------ -.. automodule:: openflexure_microscope.task - :members: - -Lock module ------------ -.. automodule:: openflexure_microscope.lock - :members: Default plugins --------------- diff --git a/docs/source/plugins/example/plugin.py b/docs/source/plugins/example/plugin.py index d26c3fe8..5d8c0e93 100644 --- a/docs/source/plugins/example/plugin.py +++ b/docs/source/plugins/example/plugin.py @@ -2,6 +2,8 @@ from openflexure_microscope.plugins import MicroscopePlugin from openflexure_microscope.api.v1.views import MicroscopeViewPlugin from openflexure_microscope.api.utilities import JsonResponse +from openflexure_microscope.common.tasks import taskify + import os import time import json @@ -139,9 +141,7 @@ class TimelapseAPI(MicroscopeViewPlugin): n_images = payload.param("n_images", default=10, convert=int) # Attach the long-running method as a microscope task - self.timelapse_task = self.microscope.task.start( - self.plugin.timelapse, n_images - ) + self.timelapse_task = taskify(self.plugin.timelapse)(n_images) # Return the state of the task (will show ID, start time, and status before the task has finished) return jsonify(self.timelapse_task.state), 202 diff --git a/docs/source/plugins/hardware.rst b/docs/source/plugins/hardware.rst index 8531a280..ebea6cd8 100644 --- a/docs/source/plugins/hardware.rst +++ b/docs/source/plugins/hardware.rst @@ -21,8 +21,8 @@ Tasks are introduced to manage long-running functions in a way that does not blo the use of tasks, long-running functions would block an HTTP response until the function returns, often resulting in a timeout. -To prevent this, any function can be offloaded to a background task. This is done through the microscope's ``task`` object, -by calling ``.task.start(, *args, **kwargs)``. Internally, the ``task`` object stores a list +To prevent this, any function can be offloaded to a background task. This is done through the :py:meth:`openflexure_microscope.common.tasks.taskify` +function, by calling ``taskify()(*args, **kwargs)``. Internally, the ``tasks`` submodule stores a list of all requested tasks, which themselves contain a ``state`` dictionary. This dictionary stores the status of the task (if it is idle, running, error, or success), information about the start and end times, a unique task ID, and the return value of the long-running function. @@ -38,17 +38,13 @@ An example of a long running task may look like: .. code-block:: python from openflexure_microscope.plugins import MicroscopeViewPlugin - from openflexure_microscope.exceptions import TaskDeniedException + from openflexure_microscope.common.tasks import taskify class MyPlugin(MicroscopeViewPlugin): def post(self): # Attach the long-running method as a microscope task - try: - self.my_task = self.microscope.task.start(self.plugin.long_running_function) - return jsonify(self.my_task.state), 202 - - except TaskDeniedException: - return abort(409) + self.my_task = taskify(self.plugin.long_running_function)() + return jsonify(self.my_task.state), 202 After some time, once the task has completed, it could be retreived using: @@ -67,7 +63,7 @@ the microscope hardware. For example, even if the stage is not actively moving ( within a tile scan), another user should not be able to move the microscope, interrupting the task. Thread locks act to prevent this. -The camera and stage both contain an instance of :py:class:`openflexure_microscope.lock.StrictLock`, named ``lock``. +The camera and stage both contain an instance of :py:class:`openflexure_microscope.common.lock.StrictLock`, named ``lock``. Built-in functions such as capture and move will always acquire this lock for the duration of the function. This ensures that, for example, simultaneous attemps to move do not occur. diff --git a/openflexure_microscope/__init__.py b/openflexure_microscope/__init__.py index e1ee2c30..87999abd 100644 --- a/openflexure_microscope/__init__.py +++ b/openflexure_microscope/__init__.py @@ -5,4 +5,4 @@ from .microscope import Microscope from . import config from . import utilities from . import task -from . import lock +from . import common diff --git a/openflexure_microscope/camera/base.py b/openflexure_microscope/camera/base.py index ea961629..09b9949d 100644 --- a/openflexure_microscope/camera/base.py +++ b/openflexure_microscope/camera/base.py @@ -10,7 +10,7 @@ from abc import ABCMeta, abstractmethod from .capture import CaptureObject from openflexure_microscope.utilities import entry_by_id -from openflexure_microscope.lock import StrictLock +from openflexure_microscope.common.lock import StrictLock BASE_CAPTURE_PATH = os.path.join(os.path.expanduser("~"), "micrographs") @@ -94,7 +94,7 @@ class BaseCamera(metaclass=ABCMeta): Attributes: thread: Background thread reading frames from camera camera: Camera object - lock (:py:class:`openflexure_microscope.lock.StrictLock`): Strict lock controlling thread + lock (:py:class:`openflexure_microscope.common.lock.StrictLock`): Strict lock controlling thread access to stage hardware frame (bytes): Current frame is stored here by background thread last_access (time): Time of last client access to the camera diff --git a/openflexure_microscope/lock.py b/openflexure_microscope/common/lock.py similarity index 98% rename from openflexure_microscope/lock.py rename to openflexure_microscope/common/lock.py index 922d508f..d96fae30 100644 --- a/openflexure_microscope/lock.py +++ b/openflexure_microscope/common/lock.py @@ -41,7 +41,7 @@ class StrictLock(object): class CompositeLock(object): """ - Class that behaves like a :py:class:`openflexure_microscope.lock.StrictLock`, + Class that behaves like a :py:class:`openflexure_microscope.common.lock.StrictLock`, but allows multiple locks to be acquired and released. Args: diff --git a/openflexure_microscope/microscope.py b/openflexure_microscope/microscope.py index 268e3c42..2df04d81 100644 --- a/openflexure_microscope/microscope.py +++ b/openflexure_microscope/microscope.py @@ -6,15 +6,14 @@ import logging import pkg_resources import uuid -from .stage.base import BaseStage +from openflexure_microscope.stage.base import BaseStage -from .camera.base import BaseCamera +from openflexure_microscope.camera.base import BaseCamera -from .plugins import PluginMount -from .utilities import axes_to_array -from .task import TaskOrchestrator -from .lock import CompositeLock -from .config import OpenflexureSettingsFile, settings_to_json +from openflexure_microscope.plugins import PluginMount +from openflexure_microscope.task import TaskOrchestrator +from openflexure_microscope.common.lock import CompositeLock +from openflexure_microscope.config import OpenflexureSettingsFile, settings_to_json class Microscope: @@ -26,7 +25,7 @@ class Microscope: Attributes: settings_file (:py:class:`openflexure_microscope.config.OpenflexureSettingsFile`): Runtime-config object, automatically created if None. - lock (:py:class:`openflexure_microscope.lock.CompositeLock`): Composite lock controlling thread access + lock (:py:class:`openflexure_microscope.common.lock.CompositeLock`): Composite lock controlling thread access to multiple pieces of hardware. camera (:py:class:`openflexure_microscope.camera.base.BaseCamera`): Camera object stage (:py:class:`openflexure_microscope.stage.base.BaseStage`): Stage object diff --git a/openflexure_microscope/stage/base.py b/openflexure_microscope/stage/base.py index 55ddbfba..05b69a9c 100644 --- a/openflexure_microscope/stage/base.py +++ b/openflexure_microscope/stage/base.py @@ -1,11 +1,11 @@ from abc import ABCMeta, abstractmethod -from openflexure_microscope.lock import StrictLock +from openflexure_microscope.common.lock import StrictLock class BaseStage(metaclass=ABCMeta): """ Attributes: - lock (:py:class:`openflexure_microscope.lock.StrictLock`): Strict lock controlling thread + lock (:py:class:`openflexure_microscope.common.lock.StrictLock`): Strict lock controlling thread access to camera hardware """