BetterDevice

class ska_tango_base.BetterDevice[source]

Bases: Device

A base class to deal with the shortcomings of tango.server.Device.

The allow_internal_threads() context manager releases the Tango device monitor lock without allowing external client threads to acquire the monitor. This can be used to allow internal threads that can potentially acquire the monitor to run e.g. during shutdown of the thread. This is required to clean up a thread that pushes events from the delete_device() method.

Subclasses of BetterDevice should always ensure that the super().always_executed_hook() is called when overriding always_executed_hook().

__init__(*args: Any, **kwargs: Any) None[source]

Initialise object.

init_device() None[source]

Initialise the device.

delete_device() None[source]

Delete the device.

device_exported_hook() None[source]

Set up device once device and server have been exported.

This hook can be used to subscribe to events, even if to devices in the same device server, such as a self subscription.

allow_internal_threads() Iterator[None][source]

Allow internal threads to run without allowing new Tango requests.

This is intended to be used from a Tango client request thread to allow internal threads to acquire the Tango monitor, without allowing another Tango request to start.

This is used in the following two places in ska-tango-base:

1. During delete_device() to allow background threads to cleanup gracefully and be joined.

If we allow other threads to run during init_device() or delete_device(), a client could initiate a new request on our device as the Tango client thread is able to grab the device lock. This should be avoided because the device is only partially initialised. This method avoids this issue by arranging for Tango client threads to be disallowed from grabbing the Tango monitor, while still allowing other internal threads to acquire the monitor.

2. At the start of every request to allow the signal bus thread to catch up.

This ensures that Tango clients get a sequentially consistent view of the Tango device. That is, if they call a command which modifies the value of an attribute then read that attribute, they will see the updated value, even if the attribute is using the signal bus (e.g. via attribute_from_signal).

always_executed_hook() None[source]

Stall incoming request if we are only allowing internal threads.