Long Running Commands
Note
The LRC Client API has been moved to its own page, as it will be updated in a future release to be compatible with any SKA Tango command - fast or long running.
This module implements a mixin class for long running commands.
The mixin requires the class using it to also inherit from the generic
SKADevice class.
- class ska_tango_base.long_running_commands.mixin.LRCReqType[source]
Used to discriminate between command is allowed callers.
- ENQUEUE_REQ = 1
Passed to is_<Cmd>_allowed when the task is submitted.
- EXECUTE_REQ = 2
Passed to is_<Cmd>_allowed when the task is about to be executed.
- class ska_tango_base.long_running_commands.mixin.LRCMixin[source]
Bases:
AbstractLRCMixinMixin class that adds support for long running commands with a task executor.
It must be used with
SKADeviceor a subclass of it. It uses a shared bus with a command tracker to manage long running commands and the related user-facing Tango attributes.- lrcQueue: list[str]
Tango attribute returning a table describing queued long running commands.
Each element of the list is a JSON object with the following keys:
"uid"- Unique identifier for the command (str)"name"- Name of the command (str)"submitted_time"- Timestamp when the command was submitted (str)
- lrcExecuting: list[str]
Tango attribute returning a table describing currently executing long running commands.
Each element of the list is a JSON object with the following keys:
"uid"- Unique identifier for the command (str)"name"- Name of the command (str)"submitted_time"- Timestamp when the command was submitted (str)"started_time"- Timestamp when the command was started (str)"progress"- Percentage completion (optional,int)
- lrcFinished: list[str]
Tango attribute returning a table describing finished long running commands.
Each element of the list is a JSON object with the following keys:
"uid"- Unique identifier for the command (str)"name"- Name of the command (str)"submitted_time"- Timestamp when the command was submitted (str)"started_time"- Timestamp when the command was started (str)"finished_time"- Timestamp when the command finished (str)"result"- JSON encoded result of command (str)"status"- TaskStatus the command finished with (str)"progress"- Percentage completion (optional,int)
- create_task_executor() TaskExecutorProtocol[source]
Create and return a task executor instance.
This factory method can be overridden in a device using the
LRCMixinclass to use its own task executor.- Returns:
Task executor instance.
- schedule_abort_task(task_callback: TaskCallbackType) tuple[TaskStatus, str][source]
Schedule an Abort task to begin executing immediately.
Subclasses should override this to change the behaviour of the Abort command.
- Parameters:
task_callback – Notified of progress of the abort command.
- Returns:
A tuple containing TaskStatus.IN_PROGRESS and a message
- property task_executor: TaskExecutorProtocol
Get the task executor.
- Returns:
The initialised task executor.
- class ska_tango_base.long_running_commands.mixin.AbstractLRCMixin[source]
Bases:
SignalBusMixinPartial mixin class that adds support for long running commands.
It must be used with
SKADeviceor a subclass of it. It uses a shared bus with a command tracker to manage long running commands and the related user-facing Tango attributes. Atask_executormust be implemented for a long running command and the related attributes to behave correctly.- on_new_shared_bus() None[source]
Initialise attributes which depend on signals from the bus.
- Raises:
AssertionError – If ‘self.task_executor.max_queued_tasks’ or ‘self.task_executor.max_executing_tasks’ is not equal to or greater than 0 or 1 respectively.
- property command_tracker: CommandTrackerProtocol
Get the command tracker.
- Returns:
The initialised
CommandTrackerProtocolobject.
- property task_executor: TaskExecutorProtocol
Get the task executor.
- Returns:
The initialised task executor.
- lrcProtocolVersions() tuple[int, int]
Return supported protocol versions.
- Returns:
A tuple containing the lower and upper bounds of supported long running command protocol versions.
- is_Abort_allowed() bool[source]
Return whether the
Abort()command may be called currently.This method can be overridden by subclasses to change when this command is allowed.
- Returns:
whether the command may be called in the current device state
- Abort() DevVarLongStringArrayType
Abort any executing long running command(s) and empty the queue.
Abort is itself a long running command that is executed immediately.
Subclasses should override
execute_Abort()to change the behaviour of this command.- Returns:
A tuple containing ResultCode.STARTED and the unique ID of the command
- allocate_lrc(name: str, *, started_callback: Callable[[...], None] | str | None = None, completed_callback: Callable[[...], None] | str | None = None) tuple[str, TaskCallbackType][source]
Allocate a new command_id for a long running command.
The status and progress of the long running command should be updated using the returned task_callback object.
- Parameters:
name – The name of the command
started_callback – Callback passed to the command tracker that is called when the command transitions to
IN_PROGRESSstatus. If a str, this will be used to look up a callable on the self. If None the default name of “started_<Cmd>” will be used.completed_callback – Callback passed to the command tracker that is called when the command transitions to
COMPLETEDstatus. If a str, this will be used to look up a callable on the self. If None the default name of “completed_<Cmd>” will be used.
- Returns:
(command_id, task_callback)
- static convert_submission_result_to_lrc_return(command_id: str, status: TaskStatus, message: str) DevVarLongStringArrayType[source]
Convert a submit result to a DevVarLongStringArray.
Example:
@command def MyCommand(self) -> DevVarLongStringArrayType: command_id, task_callback = self.allocate_lrc("MyCommand") status, message = self.submit_lrc_task( "MyCommand", self.do_my_command, task_callback ) return self.submit_result_to_lrc_return( command_id, status, message )
- Parameters:
command_id – The command id of the LRC
status – The task status returned by submit
message – The message returned by submit
- Returns:
[converted ResultCode], [command_id or message]
- submit_lrc_task(name: str, task: TaskFunctionType, *, args: list[Any] | None = None, kwargs: dict[str, Any] | None = None, task_callback: TaskCallbackType | None = None, fisallowed: Callable[[LRCReqType], bool] | str | None = None) tuple[TaskStatus, str][source]
Submit a long running command task to the task_executor.
The f”is_{name}_allowed” method is looked up and, if found, will be called with
LRCReqType.EXECUTE_REQimmediately before the task is executed.- Parameters:
task – task to be executed
args – positional arguments to be passed to the task
kwargs – keyword arguments to be passed to the task
fisallowed – override the is_cmd_allowed method used
- Returns:
TaskStatus, message
- execute_Abort() DevVarLongStringArrayType[source]
Execute the Abort command.
Subclasses should override this to change the behaviour of the Abort command.
- Returns:
A tuple containing TaskStatus.IN_PROGRESS and a message
- schedule_abort_task(task_callback: TaskCallbackType) tuple[TaskStatus, str][source]
Schedule an Abort task to begin executing immediately.
Subclasses should override this to change the behaviour of the Abort command.
- Parameters:
task_callback – Notified of progress of the abort command.
- Returns:
A tuple containing TaskStatus.IN_PROGRESS and a message
Decorators for working with long running commands.
- ska_tango_base.long_running_commands.decorators.long_running_command(*, fisallowed: Callable[[...], bool] | str | None = None, **cmd_kwargs: Any) Callable[[Callable[[...], Callable[[...], Any]]], Callable[[...], tuple[list[ResultCode], list[str]]]][source]
- ska_tango_base.long_running_commands.decorators.long_running_command(task_factory: Callable[[...], Callable[[...], Any]], *, fisallowed: Callable[[...], bool] | str | None = None, **cmd_kwargs: Any) Callable[[...], tuple[list[ResultCode], list[str]]]
Mark a method as a long running command.
Wraps a method that returns a task with common boilerplate code for a long running command and submits the task to the task executor of the device. The wrapped task factory MUST be a method in a class that inherits from LRCMixin.
The
fisallowedparameter expects a device class method with a keyword argumentrequest_typethat defaults toLRCReqType.ENQUEUE_REQ, or the name of such a method available on the device. The method will be called at submission time with the default keyword argument and will be called at execution timerequest_type=LRCReqType.EXECUTE_REQ. The function is expected to returnFalse, if the task cannot be enqueued or executed. Alternatively,fisallowedmay raise an exception to provide a more detailed error message.If
fisallowedis not provided, then the default method name of “is_<cmd>_allowed” will be looked up on the device. If this is not found, then it will be assumed that the task can awalys be enqueued and executed.- Parameters:
task_factory – An LRCMixin subclass method that returns a task.
fisallowed – Whether the task is allowed to execute. Called when command is added to the LRC queue (ENQUEUE_REQ) and immediately before execution (EXECUTE_REQ).
cmd_kwargs – Passed on to the tango.server.command call.
- Returns:
A Tango command that submits the task to the long running command queue.
- ska_tango_base.long_running_commands.decorators.submit_lrc_task(*, cmd_name: str | None = None, fisallowed: Callable[[...], bool] | str | None = None, started_callback: Callable[[...], None] | str | None = None, completed_callback: Callable[[...], None] | str | None = None) Callable[[Callable[[...], Callable[[...], Any]]], Callable[[...], tuple[list[ResultCode], list[str]]]][source]
- ska_tango_base.long_running_commands.decorators.submit_lrc_task(task_factory: Callable[[...], Callable[[...], Any]], *, cmd_name: str | None = None, fisallowed: Callable[[...], bool] | str | None = None, started_callback: Callable[[...], None] | str | None = None, completed_callback: Callable[[...], None] | str | None = None) Callable[[...], tuple[list[ResultCode], list[str]]]
Submit a task returned by task_factory to the TaskExecutor.
Wraps a method that returns a task with common boilerplate code for a long running command and submits the task to the task executor of the device. The wrapped task factory MUST be a method in a class that inherits from LRCMixin.
The
fisallowedparameter expects a device class method with a keyword argumentrequest_typethat defaults toLRCReqType.ENQUEUE_REQ, or the name of such a method available on the device. The method will be called at submission time with the default keyword argument and will be called at execution timerequest_type=LRCReqType.EXECUTE_REQ. The function is expected to returnFalse, if the task cannot be enqueued or executed. Alternatively,fisallowedmay raise an exception to provide a more detailed error message.If
fisallowedis not provided, then the default method name of “is_<cmd>_allowed” will be looked up on the device. If this is not found, then it will be assumed that the task can always be enqueued and executed.- Parameters:
task_factory – An LRCMixin subclass method that returns a task.
fisallowed – Whether the task is allowed to execute. Called when command is added to the LRC queue (ENQUEUE_REQ) and immediately before execution (EXECUTE_REQ).
started_callback – Callback passed to the command tracker that is called when the command transitions to
IN_PROGRESSstatus.completed_callback – Callback passed to the command tracker that is called when the command transitions to
COMPLETEDstatus.
- Returns:
The wrapped function
- ska_tango_base.long_running_commands.decorators.mark_long_running(fn: Any) Any[source]
Mark a
executing_<Cmd>()method as a long running command.This is used by the default
is_<Cmd>_allowed()methods to know that they should not check the state machine when the Tango command is initially called and instead wait for theis_<Cmd>_allowed()method to be called later withLRCReqType.EXECUTE_REQwhen the task is about to be executed.Warning
This decorator does not arrange for the
is_<Cmd>_allowed()method to be called withLRCReqType.EXECUTE_REQ. For this use thesubmit_lrc_task()decorator orsubmit_lrc_task().