@@ -9,19 +9,34 @@ from openflexure_microscope.utilities import entry_by_id
classTaskOrchestrator:
def__init__(self):
# List of tasks in the orchestrator
self.tasks=[]
"""
Class responsible for spawning threaded tasks, and storing their returns.
A microscope should contain exactly one instance of `TaskOrchestrator`.
"""
self.tasks=[]#: list: List of `Task` objects
@property
defstate(self):
"""
Returns a list of dictionary representations of all tasks in the session.
"""
return[task.statefortaskinself.tasks]
deftask_from_id(self,task_id):
deftask_from_id(self,task_id:str):
"""
Returns a particular task object with the specified `task_id`.
"""
returnentry_by_id(task_id,self.tasks)
defstart(self,function,*args,**kwargs):
defstart(self,function:function,*args,**kwargs):
"""
Attach and start a new long-running task, if allowed by `start_condition()`.
Returns an instance of :py:class:`openflexure_microscope.task.Task`, which can be used to check the state
or eventual return of the task.
Args:
function (function): The target function to run in the background
*args, **kwargs: Arguments that will be passed to `function` at runtime.
"""
# Create a task object
task=Task(function,*args,**kwargs)
@@ -65,16 +80,18 @@ class TaskOrchestrator:
classTask:
def__init__(self,task,*args,**kwargs):
"""
Class responsible for running a task function in a thread, and handling return or errors.
Tasks should be created by an instance of :py:class:`openflexure_microscope.task.TaskOrchestrator`.
"""
# The task long-running method
self.task=task
self.args=args
self.kwargs=kwargs
self.task=task#: function: Function to be called in the task thread.
self.args=args#: Positional arguments to be passed to the task function.
self.kwargs=kwargs#: Keyword arguments to be passed to the task function.
# If task is currently running
self._running=False
self._running=False#: bool: If task is currently running
self.id=uuid.uuid4().hex
self.id=uuid.uuid4().hex#: str: Unique ID for the task
self.state={
'id':self.id,
@@ -82,9 +99,12 @@ class Task:
'return':None,
'start_time':None,
'end_time':None,
}
}#: dict: Dictionary describing the full state of the task. `status` will be one of 'idle'', 'running', 'error', or 'success'. `return` eventually holds the return value of the task function.
defprocess(self,f):
"""
Wraps the target function to handle recording `status` and `return` to `state`.
"""
defwrapped(*args,**kwargs):
self.state['status']='running'
try:
@@ -98,12 +118,18 @@ class Task:
returnwrapped
defrun(self):
"""
Records the task start and end times to `state`, and runs the task wrapped in `process`.