devsup Package¶
-
NO_ALARM, MINOR_ALARM, MAJOR_ALARM, INVALID_ALARM
Constants for alarm severity. Use with
Record.setSevr
-
NO_ALARM, READ_ALARM, WRITE_ALARM, ...
Constants for alarm status. Use with
Record.setSevr
db
Module¶
-
devsup.db.
getRecord
(name)¶ Retrieve a
Record
instance by the full record name.The result is cached so the future calls will return the same instance. This is the preferred way to get
Record
instances.>>> R = getRecord("my:record:name") Record("my:record:name")
Record
Class¶
-
class
devsup.db.
Record
¶ Allows access to a single record instance. Record instances can be created for any record in the process database. However, some features will only function when the record has Python device support.
Record objects allow access to fields through the
field()
method and direct access to field values through attributes.Attribute access is currently limited to scalar fields.
>>> R = getRecord("my:record:name") >>> F = R.field('VAL') >>> F.getval() 42 >>> R.VAL 42 >>> R.VAL = 43
-
name
() → str¶ Record name.
R = getRecord("my:record:name") assert R.name()=="my:record:name"
-
rtype
() → str¶ Return record type name string
-
field
(name)¶ Lookup field in this record
Return type: Field
Throws: KeyError for non-existent fields. The returned object is cached so future calls will return the same instance.
>>> getRecord("rec").field('HOPR') Field("rec.HOPR")
-
setSevr
(sevr=INVALID_ALARM, stat=COMM_ALARM)¶ Set alarm new alarm severity/status. Record must be locked!
-
setTime
(ts)¶ Set record timestamp.
Parameters: ts – datetime, float, or (sec, nsec). Has not effect if the TSE field is not set to -2. All inputs must be referenced to the posix epoch.
If a datetime is provided, it must use the local system timezone.
-
scan
(sync=False, reason=None, force=0)¶ Scan this record.
Parameters: - sync – scan in current thread (
True
), or queue to a worker (False
). - reason – Reason object passed to
process
(sync=True only) - force – Record processing condtion (0=Passive, 1=Force, 2=I/O Intr)
Throws: RuntimeError
whensync=True
, butforce
prevents scanning.If
sync
is False then a scan request is queued to run in another thread.. Ifsync
is True then the record is scanned immediately on the current thread.For
reason
argument must be used in conjunction withsync=True
on records with Python device support. This provides a means of providing extra contextual information to the record’sprocess
method.force
is used to decide if the record will actually be processed,force=0
will only process records with SCAN=Passive.force=1
will process any record if at all possible.force=2
will only process records with Python device support and SCAN=I/O Intr.Important
It is never safe to use
sync=True
while holding record locks, including from within a process method.- sync – scan in current thread (
-
asyncStart
()¶ Start asynchronous processing
This method may be called from a device support
process
method to indicate that processing will continue later.Important
This method is only safe to call within a process method.
-
asyncFinish
(reason=None)¶ Indicate that asynchronous processing can complete
Similar to
scan()
. Used to conclude asynchronous process started withasyncStart()
.Processing is completed on the current thread.
Important
This method should never be called within a
process
method, or any other context where a Record lock is held. Doing so will result in a deadlock.Typically a reason will be passed to process as a way of indicating that this is the completion of an async action.
AsyncDone = object() class MySup(object): def process(record, reason): if reason is AsyncDone: record.VAL = ... # store result else: threading.Timer(1.0, record.asyncFinish, kwargs={'reason':AsyncDone}) record.asyncStart()
-
info
(key[, default]) → str¶ Lookup info by name :rtype: str :throws: KeyError
-
infos
() → {'name':'value'}¶ Return a dictionary of all infos for this record.
-
Field
Class¶
-
class
devsup.db.
Field
¶ -
name
() -> (recname, fldname)¶
-
getval
() → object¶
-
putval
(object)¶
-
getarray
() → numpy.ndarray¶ Return a numpy ndarray refering to this field for in-place operations.
-
getarraylen
() → int¶ Return current number of valid elements for array fields.
-
putarraylen
(int)¶ Set number of valid elements for array fields.
-
fieldinfo
() → (dbf, elem_size, elem_count¶
-
getTime
()¶ Get timestamp of link target.
Only works for DBF_INLINK fields. Returns the time in seconds since the POSIX epoch.
Return type: float
-
getAlarm
() → (severity, status).¶
-
-
class
devsup.db.
IOScanListBlock
¶ A list of records which will be processed together.
This convenience class to handle the accounting to maintain a list of records.
-
add
(rec)¶ Add a record to the scan list.
This method is designed to be consistent with
allowScan
by returning itsremove()
method. If fact this function can be completely delegated.class MyDriver(util.StoppableThread): def __init__(self): super(MyDriver,self).__init__() self.lock = threading.Lock() self.scan1 = IOScanListBlock() def run(self): while self.shouldRun(): time.sleep(1) with self.lock: self.scan1.interrupt() class MySup(object): def __init__(self, driver): self.driver = driver def allowScan(rec): with self.driver.lock: return self.driver.scan1.add(rec)
-
interrupt
(reason=None, mask=None)¶ Scan the records in this list.
Parameters: - reason – Passed to
Record.scan()
. - mask – A list or set or records which should not be scanned.
Returns: True
This method will call
Record.scan()
of each of the records currently in the list. This is done synchronously in the current thread. It should never be call when any record locks are held.- reason – Passed to
-
remove
(rec)¶ Remove a record from the scan list.
-
-
class
devsup.db.
IOScanListThread
¶ A list of records w/ a worker thread to run them.
All methods are thread-safe.
-
add
(rec)¶ Add a record to the scan list.
This method is thread-safe and may be used without additional locking.
class MyDriver(util.StoppableThread): def __init__(self): super(MyDriver,self).__init__() self.scan1 = IOScanListThread() def run(self): while self.shouldRun(): time.sleep(1) self.scan1.interrupt() class MySup(object): def __init__(self, driver): self.driver = driver self.allowScan = self.driver.scan1.add
-
interrupt
(reason=None, mask=None, whendone=<function _default_whendone>)¶ Queue a request to process the scan list.
Parameters: - reason – Passed to
Record.scan()
. - mask – A list or set or records which should not be scanned.
- whendone – A callable which will be invoked after all records are processed.
Returns: True is the request was queued, and False if the queue was full.
Throws: RuntimeError is the request can’t be queued.
Calling this method will cause a request to be sent to a worker thread. This method can be called several times to queue several requests.
If provided, the whendone callable is invoked with three arguments. These will be None except in the case an interrupt is raised in the worker in which case they are: exception type, value, and traceback.
Note
This method may be safely called while record locks are held.
- reason – Passed to
-
hooks
Module¶
-
devsup.hooks.
addHook
("stats", funcion)¶ Add callable to IOC start sequence.
Callables are run in the order in which they were added (except for ‘AtIocExit’).
>>> def show(): ... print('State Occurred') >>> addHook("AfterIocRunning", show)
An additional special hook ‘AtIocExit’ may be used for cleanup actions during IOC shutdown.
-
devsup.hooks.
initHook
(state)¶ Decorator for initHook functions
@initHook(“AfterIocRunning”) def myfn():
pass
-
devsup.hooks.
debugHooks
()¶ Install debugging print to hooks
util
Module¶
-
class
devsup.util.
StoppableThread
(max=0)¶ Bases:
threading.Thread
A thread which can be requested to stop.
The thread run() method should periodically call the shouldRun() method and return if this yields False.
>>> class TestThread(StoppableThread): ... def __init__(self): ... super(TestThread,self).__init__() ... self.E=threading.Event() ... def run(self): ... import time ... self.cur = threading.current_thread() ... self.E.set() ... while self.shouldRun(): ... self.sleep(10.0) >>> T = TestThread() >>> T.start() >>> T.E.wait(1.0) True >>> T.cur is T True >>> T.join() >>> T.is_alive() False
-
join
()¶ Wait until the thread terminates.
This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception or until the optional timeout occurs.
When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.
When the timeout argument is not present or None, the operation will block until the thread terminates.
A thread can be join()ed many times.
join() raises a RuntimeError if an attempt is made to join the current thread as that would cause a deadlock. It is also an error to join() a thread before it has been started and attempts to do so raises the same exception.
-
shouldRun
()¶ Returns False is a request to stop is made.
-
sleep
(delay)¶ Sleep for some time, or until a request to stop is made. Return value is the same as shouldRun()
-
start
()¶ Start the thread’s activity.
It must be called at most once per thread object. It arranges for the object’s run() method to be invoked in a separate thread of control.
This method will raise a RuntimeError if called more than once on the same thread object.
-
-
class
devsup.util.
Worker
(max=0)¶ Bases:
threading.Thread
A threaded work queue.
>>> w = Worker() >>> w.start() >>> w.join() >>> import threading >>> E = threading.Event() >>> w = Worker() >>> w.start() >>> w.add(E.set) True >>> E.wait(1.0) True >>> w.join()
-
StopWorker
= <object object>¶
-
add
(func, args=(), kws={}, block=True)¶ Attempt to send a job to the worker.
Returns: True if the job was queued. False if the queue is full, or has been joined. When
block=True
then this method will only return False if the Worker has been joined.
-
join
(flush=True)¶ Stop accepting new jobs and join the worker thread
Blocks until currently queued work is complete.
-
run
()¶ Method representing the thread’s activity.
You may override this method in a subclass. The standard run() method invokes the callable object passed to the object’s constructor as the target argument, if any, with sequential and keyword arguments taken from the args and kwargs arguments, respectively.
-
-
devsup.util.
importmod
(modname)¶ Import the named python module(s) add return the leaf.
>>> M=importmod('xml.sax') >>> M.__name__ 'xml.sax' >>>
disect
Module¶
Python reference counter statistics.
-
class
devsup.disect.
StatsDelta
¶ GC statistics tracking.
Monitors the number of instances of each type/class (cf. gcstats()) and prints a report of any changes (ie. new types/count changes). Intended to assist in detecting reference leaks.
-
collect
(file=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>)¶ Collect stats and print results to file
Parameters: file – A writable file-like object
-
reset
()¶ Reset internal statistics counters
-
-
devsup.disect.
gcstats
()¶ Count the number of instances of each type/class
Returns: A dict() mapping type (as a string) to an integer number of references
-
devsup.disect.
periodic
(period=60.0, file=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>)¶ Start a daemon thread which will periodically print GC stats
Parameters: - period – Update period in seconds
- file – A writable file-like object