AckCmdReader

class lsst.ts.salobj.topics.AckCmdReader(salinfo, queue_len=100)

Bases: lsst.ts.salobj.topics.ReadTopic

Read the ackcmd command acknowledgement topic.

Parameters:
salinfo : SalInfo

SAL component information

queue_len : int

Number of elements that can be queued for get_oldest.

Notes

The same ackcmd topic is used for all command topics from a given SAL component.

Attributes Summary

DataType The type (class) for a message of this topic.
allow_multiple_callbacks Can callbacks can run simultaneously?
callback Callback function, or None if there is not one.
has_callback Return True if there is a callback function.
has_data Has any data been seen for this topic?
max_history
metadata Get topic metadata as a TopicMetadata, if available, else None.

Methods Summary

aget([timeout]) Get the current message, if any, else wait for the next message.
close() Shut down and release resources.
flush() Flush the queue of unread data.
get([flush]) Get the most recently seen message, or None if no data ever seen.
get_oldest() Pop and return the oldest message from the queue, or None if the queue is empty.
next(*, flush[, timeout]) Wait for a message, possibly returning the oldest queued message.

Attributes Documentation

DataType

The type (class) for a message of this topic.

When you read or write a message for this topic you are reading or writing an instance of DataType.

Notes

The preferred way to write a message for a topic is:

  • RemoteCommand.set_start to start a command.
  • CommandEvent.set_put to write an event.
  • CommandTelemetry.set_put to write a telemetry message.

However, it is also possible to use DataType to create a message, then write, it as separate operations. For example, assuming we have a Remote for SAL component “Test”:

# The preferred way to issue a command:
await = remote.cmd_wait.set_put(duration=2, timeout=5)

# But an alternative is to first create the command,
# then send it, as two separate operations:
message = remote.cmd_wait.DataType(duration=2)
await remote.cmd_wait.start(message, timeout=5)

# Or, even more verbosely:
message = remote.cmd_wait.DataType()
message.duration = 2
await remote.cmd_wait.start(message, timeout=5)
allow_multiple_callbacks

Can callbacks can run simultaneously?

Notes

Ignored for synchronous callbacks because those block while running. In particular, if the callback is synchronous but launches one or more background jobs then the number of those jobs cannot be limited by this class.

callback

Callback function, or None if there is not one.

The callback function is called when a new message is received; it receives one argument: the message (an object of type topics.BaseTopic.DataType).

Raises:
TypeError

When setting a new callback if the callback is not None and is not callable.

Notes

The callback function can be synchronous or asynchronous (e.g. defined with async def).

Setting a callback flushes the queue, and it will remain empty as long as there is a callback.

get_oldest and next are prohibited if there is a callback function. Technically they could both work, but get_oldest would always return None and next would miss messages if they arrived while waiting for something else. It seemed safer to just raise an exception.

has_callback

Return True if there is a callback function.

has_data

Has any data been seen for this topic?

Raises:
RuntimeError

If the salinfo has not started reading.

max_history
metadata

Get topic metadata as a TopicMetadata, if available, else None.

Methods Documentation

aget(timeout=None)

Get the current message, if any, else wait for the next message.

Parameters:
timeout : float, optional

Time limit, in seconds. If None then no time limit.

Returns:
data : DataType

The current or next message.

Raises:
RuntimeError

If a callback function is present, or if the salinfo has not started reading.

Notes

Do not modify the returned data. To make a copy that you can safely modify, use copy.copy(data).

close()

Shut down and release resources.

Intended to be called by SalInfo.close(), since that tracks all topics.

flush()

Flush the queue of unread data.

Raises:
RuntimeError

If a callback function is present.

get(flush=True)

Get the most recently seen message, or None if no data ever seen.

Parameters:
flush : bool, optional

Flush the queue? Defaults to True for backwards compatibility. This only affects the next message returned by next and is ignored if there is a callback function.

Returns:
data : self.DataType or None

Return self.data if data has been read, else None.

Raises:
RuntimeError

If the salinfo has not started reading.

get_oldest()

Pop and return the oldest message from the queue, or None if the queue is empty.

Returns:
data : self.DataType or None

The oldest message found on the queue, if any, else None.

Raises:
RuntimeError

If a callback function is present, or if the salinfo has not started reading.

Notes

Use with caution when mixing with next, since that also consumes data from the queue.

next(*, flush, timeout=None)

Wait for a message, possibly returning the oldest queued message.

Parameters:
flush : bool

If True then flush the queue before starting a read. If False then pop and return the oldest message from the queue, if any, else wait for new data.

timeout : float, optional

Time limit, in seconds. If None then no time limit.

Returns:
data : DataType

The message data.

Raises:
RuntimeError

If a callback function is present, or if the salinfo has not started reading.

Notes

Do not modify the returned data. To make a copy that you can safely modify, use copy.copy(data).