The low-level Python/C interface¶
The ktlc
module is the sole interface between the ktl
module
and the underlying KTL/C API. The operations performed in this module strive
to be the absolute minimum required to cleanly wrap calls to the KTL/C API;
complex operations are better handled in the ktl
module, as mistakes
in the Python half tend to be less subtle, easier to correct, and more
straight-forward to test.
Because all calls to the ktlc
module are filtered by an Usher
thread, no great effort was made to ensure thread-safety internal to the module
itself. On the contrary, the only concessions made by the ktlc
module
to thread-awareness are to release the Python interpreter to execute other
threads if a KTL call will obviously block, such as a KTL_WAIT
invocation
of read()
or write()
.
Functions¶
-
ktlc.
dumpster
(append, stop)¶ Set the function reference that will be used to hand off
Trash
instances to theJanitor
for disposal.
-
ktlc.
probe
(service, keyword)¶ Open a new instance of the KTL client library for the designated service, and attempt to read a value for keyword. Upon completion, close the newly opened instance of service. This is done independently of any cached metadata elsewhere in
ktlc
, as the encapsulated read is used by theFirstResponder
thread to determine whether the already open KTL handle is no longer functioning. The read values are not returned, as they are not significant for this purpose.If a component of the
ktl
module were constructed as a.sin
(substitution) file, this mechanism would not be necessary, as the Python module could instead invoke$RELDIR/bin/show
via thesubprocess
module. While less efficient, it would eliminate the possibility of a client library itself being clever about reusing cached resources.
Classes¶
-
class
ktlc.
Service
¶ The
Service
class is a low-level interface to service-specific KTL functions. In addition, it contains a dictionary ofKeyword
instances, populated on a just-in-time basis for use by the Python layers of the KTL Python module. A direct reference to aService
instance must be maintained in order for theKeyword
instances to remain functional.-
descriptors
()¶ Determine which file descriptors, if any, are associated with this
Service
instance. Returns a tuple of file descriptor numbers, as integers. If no descriptors are available, an empty tuple will be returned.
-
dispatch
()¶ Process pending KTL events for this
Service
by invokingktl_dispatch()
.dispatch()
will return the total number of events dispatched.
-
headers
()¶ Enumerate the keywords and associated FITS comments for this
Service
. Returns a tuple of tuples, each of which will contain a keyword name and a FITS comment. If no such values are available, an empty tuple will be returned.Note
The keyword values normally returned with the ‘oneshot’ are completely ignored. This may be modified in a future version, but in general a less intensive approach should be adopted to acquire and format keyword values. This function exists solely to enable easy transitions to such mechanisms.
-
list
()¶ List all of the keywords available in this
Service
instance. The list is populated when the Service is first instantiated, and will not change for the duration of its existence.
Significant attributes of the
Service
class:-
name
¶ Service name
-
notify
¶ support for KTL_NOTIFY reads
-
-
class
ktlc.
Keyword
¶ The
Keyword
class is a low-level interface to keyword-specific KTL functions. Direct references toKeyword
instances do not need to be retained, but the high-level KTL Python interface does so for efficiency’s sake.-
monitor
(callback)¶ Subscribe to broadcasts for this
Keyword
. A KTL callback will be registered, withreadNotifyHandler()
as the C callback function; it will in turn invoke the provided callback function, handing it a single object: a (timestamp, binary, ascii) tuple, or an exception. In practice, the only callback function ever registered withmonitor()
isktl.Keyword._update()
. If callback is set to False, the subscription to broadcasts (if any) for thisKeyword
will be cancelled. This second usage is uncommon: it is more likely that a KTL service will be closed without first cancelling any active subscriptions.
-
range
()¶ Determine the allowed range of values for this
Keyword
. If a keyword has both a minimum and a a maximum, a dictionary will be returned with keys ‘minimum’ and ‘maximum’. If only one of those values is not available, None will be assigned to its place in the dictionary. If no range is available,range()
will raise aktl.ktlError
. These values are, by convention, appropriate for the binary representation of a numeric keyword. The ascii translation of those values will be in a nested and similarly constructed ‘ascii’ dictionary.
-
read
()¶ Invoke
ktl_read()
to determine the current value of this :class`Keyword`. If successful, the callback will be invoked with a (timestamp, binary, ascii) tuple for the new values. In practice, the only callback function used isktl.Keyword._update()
.read()
will performKTL_NOTIFY
reads whenever possible; when it is not,read()
will automatically fall back to performing aKTL_WAIT
read, and will manually invoke callback with the new values.Note
No values are returned by
read()
; the callback is the sole mechanism used to provide results, and will be invoked for both theKTL_NOTIFY
and theKTL_WAIT
branches.
-
units
()¶ Return the ‘units’ description associated with this
Keyword
.Note
The ‘units’ value is an array of strings, and is regularly overloaded with additional values in implementation-specific ways. Some standard uses include listing the enumerators for enumerated keyword types, and the array position names for array types.
-
write
(value, binary, wait, callback)¶ Perform a
ktl_write()
of value to thisKeyword
. If supported, aKTL_NOTIFY
write will be performed regardless of the wait argument; if not supported,KTL_NOWAIT
will be used if wait is False, andKTL_WAIT
will be used if wait is True. If binary is set to True, value will be interpreted as the binary representation; if set to False, value will instead be interpreted as the ascii representation.Warning
The use of
KTL_NOWAIT
inwrite()
does not agree with the basic KTL specification; it really should be aKTL_NOREPLY
write, as no attempt is made to match theKTL_NOWAIT
write with aktl_read(KTL_WAITFOR)
call. A switch to usingKTL_NOREPLY
here must be cautious, as many KTL implementations do not support it; some implementations instead expect this incorrect use ofKTL_NOWAIT
. There is also some disagreement about the precise arguments that should be used with aktl_read(KTL_WAITFOR)
call, which is a large part of why KTL Python chooses instead to emulate this functionality withKTL_NOTIFY
if the latter is supported.
Significant attributes of the
Keyword
class:-
-
class
ktlc.
Trash
¶ The
Trash
class is an internal construct used to safely close KTL services whoseService
instances have been deallocated. This artifice is only necessary to ensure that calls toktl_close()
originate from the same thread used to originally invokektl_open()
; in the absence of that restriction,ktl_close()
would be invoked directly when theService
instance is in the process of being deallocated.-
dispose
()¶ Invoke
ktl_close()
on any KTL handles present, and subsequently decrement the local garbage reference, if any.
-