-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Joel Collins
committed
Jul 20, 2020
1 parent
17d4f23
commit a4f3949
Showing
4 changed files
with
74 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
Action tasks | ||
============ | ||
|
||
Many actions in your LabThing may perform tasks that take a long time (compared to the expected response time of a web request). For example, if you were to implement a timelapse action, this inherently runs over a long time. | ||
|
||
This introduces a couple of problems. Firstly, a request that triggers a long function will, by default, block the Python interpreter for the duration of the function. This usually causes the connection to timeout, and the response will never be revieved. | ||
|
||
Tasks are introduced to manage long-running functions in a way that does not block HTTP requests. Any API Action will automatically run as a task. | ||
|
||
Internally, the :class:`labthings.LabThing` object stores a list of all requested actions, and their states. This state stores the running status of the action (if itis idle, running, error, or success), information about the start and end times, a unique task ID, and, upon completion, the return value of the long-running function. | ||
|
||
By using tasks, a function can be started in the background, and it's return value fetched at a later time once it has reported success. If a long-running action is started by some client, it should note the ID returned in the action state JSON, and use this to periodically check on the status of that particular action. | ||
|
||
API routes have been created to allow checking the state of all actions (GET ``/actions``), a particular task by ID (GET ``/actions/<action_id>``), and terminating or removing individual tasks (DELETE ``/actions/<action_id>``). | ||
|
||
All Actions will return a serialized representation of the task, when your POST request returns. If the task completes within a default timeout period (usually 1 second) then the completed Action representation will be returned. If the task is still running after this timeout period, the "in-progress" Action representation will be returned. The final output value can then be retrieved at a later time. | ||
|
||
Most users will not need to create instances of this class. Instead, they will be created automatically when a function is started by an API Action view. | ||
|
||
.. autoclass:: labthings.tasks.TaskThread | ||
:members: | ||
|
||
|
||
Accessing the current task | ||
++++++++++++++++++++++++++ | ||
|
||
A function running inside a :class:`labthings.tasks.TaskThread` is able to access the instance it is running in using the :meth:`labthings.current_task` function. This allows the state of the Action to be modified freely. | ||
|
||
.. autofunction:: labthings.current_task | ||
:noindex: | ||
|
||
|
||
Updating task progress | ||
++++++++++++++++++++++ | ||
|
||
Some client applications may be able to display progress bars showing the progress of an action. Implementing progress updates in your actions is made easy with the :py:meth:`labthings.update_task_progress` function. This function takes a single argument, which is the action progress as an integer percent (0 - 100). | ||
|
||
If your long running function was started within a background task, this function will update the state of the corresponding action object. If your function is called outside of a long-running task (e.g. by some internal code, not the web API), then this function will silently do nothing. | ||
|
||
.. autofunction:: labthings.update_task_progress | ||
:noindex: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
Synchronisation objects | ||
======================= | ||
|
||
|
||
Locks | ||
----- | ||
|
||
Locks have been implemented to solve a distinct issue, most obvious when considering action tasks. During a long task, it may be necesarry to block any completing interaction with the LabThing hardware. | ||
|
||
The :py:class:`labthings.StrictLock` class is a form of re-entrant lock. Once acquired by a thread, that thread can re-acquire the same lock. This means that other requests or actions will block, or timeout, but the action which acquired the lock is able to re-acquire it. | ||
|
||
.. autoclass:: labthings.StrictLock | ||
:members: | ||
:noindex: | ||
|
||
A CompositeLock allows grouping multiple locks to be simultaneously acquired and released. | ||
|
||
.. autoclass:: labthings.CompositeLock | ||
:members: | ||
:noindex: | ||
|
||
|
||
Per-Client events | ||
----------------- | ||
|
||
.. autoclass:: labthings.ClientEvent | ||
:members: | ||
:noindex: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters