logging as of 2022-02-01
Change-Id: I63c681bea9553cd822b214075b163ca6c42fe0cc
This commit is contained in:
@ -31,13 +31,21 @@ from secop.datatypes import ArrayOf, BoolType, EnumType, FloatRange, \
|
||||
IntRange, StatusType, StringType, TextType, TupleOf
|
||||
from secop.errors import BadValueError, ConfigError, \
|
||||
ProgrammingError, SECoPError, SilentError, secop_error
|
||||
from secop.lib import formatException, mkthread
|
||||
from secop.lib import formatException, mkthread, UniqueObject
|
||||
from secop.lib.enum import Enum
|
||||
from secop.params import Accessible, Command, Parameter
|
||||
from secop.poller import BasicPoller, Poller
|
||||
from secop.properties import HasProperties, Property
|
||||
from secop.logging import RemoteLogHandler, add_comlog_handler
|
||||
|
||||
Done = object() #: a special return value for a read/write function indicating that the setter is triggered already
|
||||
|
||||
class DoneClass:
|
||||
@classmethod
|
||||
def __repr__(cls):
|
||||
return 'Done'
|
||||
|
||||
|
||||
Done = UniqueObject('Done')
|
||||
|
||||
|
||||
class HasAccessibles(HasProperties):
|
||||
@ -124,20 +132,20 @@ class HasAccessibles(HasProperties):
|
||||
|
||||
def wrapped_rfunc(self, pname=pname, rfunc=rfunc):
|
||||
if rfunc:
|
||||
self.log.debug("calling %r" % rfunc)
|
||||
self.log.debug("call read_%s" % pname)
|
||||
try:
|
||||
value = rfunc(self)
|
||||
self.log.debug("rfunc(%s) returned %r" % (pname, value))
|
||||
self.log.debug("read_%s returned %r" % (pname, value))
|
||||
if value is Done: # the setter is already triggered
|
||||
return getattr(self, pname)
|
||||
except Exception as e:
|
||||
self.log.debug("rfunc(%s) failed %r" % (pname, e))
|
||||
self.log.debug("read_%s failed %r" % (pname, e))
|
||||
self.announceUpdate(pname, None, e)
|
||||
raise
|
||||
else:
|
||||
# return cached value
|
||||
self.log.debug("rfunc(%s): return cached value" % pname)
|
||||
value = self.accessibles[pname].value
|
||||
self.log.debug("return cached %s = %r" % (pname, value))
|
||||
setattr(self, pname, value) # important! trigger the setter
|
||||
return value
|
||||
|
||||
@ -158,16 +166,19 @@ class HasAccessibles(HasProperties):
|
||||
if not wrapped:
|
||||
|
||||
def wrapped_wfunc(self, value, pname=pname, wfunc=wfunc):
|
||||
self.log.debug("check validity of %s = %r" % (pname, value))
|
||||
pobj = self.accessibles[pname]
|
||||
value = pobj.datatype(value)
|
||||
if wfunc:
|
||||
self.log.debug('calling %s %r(%r)' % (wfunc.__name__, wfunc, value))
|
||||
self.log.debug("check and call write_%s(%r)" % (pname, value))
|
||||
value = pobj.datatype(value)
|
||||
returned_value = wfunc(self, value)
|
||||
self.log.debug('write_%s returned %r' % (pname, returned_value))
|
||||
if returned_value is Done: # the setter is already triggered
|
||||
return getattr(self, pname)
|
||||
if returned_value is not None: # goodie: accept missing return value
|
||||
value = returned_value
|
||||
else:
|
||||
self.log.debug("check %s = %r" % (pname, value))
|
||||
value = pobj.datatype(value)
|
||||
setattr(self, pname, value)
|
||||
return value
|
||||
|
||||
@ -176,11 +187,17 @@ class HasAccessibles(HasProperties):
|
||||
setattr(cls, 'write_' + pname, wrapped_wfunc)
|
||||
wrapped_wfunc.__wrapped__ = True
|
||||
|
||||
# check information about Command's
|
||||
# check for programming errors
|
||||
for attrname in cls.__dict__:
|
||||
if attrname.startswith('do_'):
|
||||
prefix, _, pname = attrname.partition('_')
|
||||
if not pname:
|
||||
continue
|
||||
if prefix == 'do':
|
||||
raise ProgrammingError('%r: old style command %r not supported anymore'
|
||||
% (cls.__name__, attrname))
|
||||
elif prefix in ('read', 'write') and not isinstance(accessibles.get(pname), Parameter):
|
||||
raise ProgrammingError('%s.%s defined, but %r is no parameter'
|
||||
% (cls.__name__, attrname, pname))
|
||||
|
||||
res = {}
|
||||
# collect info about properties
|
||||
@ -434,6 +451,10 @@ class Module(HasAccessibles):
|
||||
errors.append('%s: %s' % (aname, e))
|
||||
if errors:
|
||||
raise ConfigError(errors)
|
||||
self.remoteLogHandler = None
|
||||
self._earlyInitDone = False
|
||||
self._initModuleDone = False
|
||||
self._startModuleDone = False
|
||||
|
||||
# helper cfg-editor
|
||||
def __iter__(self):
|
||||
@ -579,6 +600,11 @@ class Module(HasAccessibles):
|
||||
started_callback()
|
||||
self.startModuleDone = True
|
||||
|
||||
def setRemoteLogging(self, conn, level):
|
||||
if self.remoteLogHandler is None:
|
||||
self.remoteLogHandler = RemoteLogHandler(self)
|
||||
self.remoteLogHandler.set_conn_level(conn, level)
|
||||
|
||||
|
||||
class Readable(Module):
|
||||
"""basic readable module"""
|
||||
@ -697,6 +723,10 @@ class Drivable(Writable):
|
||||
class Communicator(Module):
|
||||
"""basic abstract communication module"""
|
||||
|
||||
def initModule(self):
|
||||
super().initModule()
|
||||
add_comlog_handler(self)
|
||||
|
||||
@Command(StringType(), result=StringType())
|
||||
def communicate(self, command):
|
||||
"""communicate command
|
||||
@ -708,7 +738,7 @@ class Communicator(Module):
|
||||
|
||||
|
||||
class Attached(Property):
|
||||
"""a special property, defining an attached modle
|
||||
"""a special property, defining an attached module
|
||||
|
||||
assign a module name to this property in the cfg file,
|
||||
and the server will create an attribute with this module
|
||||
|
Reference in New Issue
Block a user