Skip to content

Commit

Permalink
Merge pull request #84 from dls-controls/notifier
Browse files Browse the repository at this point in the history
Notifier and Serializable refactor
  • Loading branch information
coretl committed Jul 13, 2016
2 parents ef9f16e + 73c0974 commit d80f6f4
Show file tree
Hide file tree
Showing 42 changed files with 300 additions and 197 deletions.
2 changes: 1 addition & 1 deletion malcolm/controllers/clientcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def _regenerate_block(self, d):
for k, v in d.items():
if k == "typeid":
continue
child = Serializable.from_dict(k, v)
child = Serializable.deserialize(k, v)
children.append(child)
if isinstance(child, Method):
# calling method forwards to server
Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Need to import these so that the register hooks are called
# Need to import these so that the register_subclass hooks are called
from malcolm.core.stringmeta import StringMeta # noqa
from malcolm.core.stringarraymeta import StringArrayMeta # noqa
from malcolm.core.numbermeta import NumberMeta # noqa
Expand Down
7 changes: 4 additions & 3 deletions malcolm/core/attribute.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from collections import OrderedDict

from malcolm.core.notifier import Notifier
from malcolm.core.serializable import Serializable


@Serializable.register("epics:nt/NTAttribute:1.0")
class Attribute(Serializable):
@Serializable.register_subclass("epics:nt/NTAttribute:1.0")
class Attribute(Notifier):
"""Represents a value with type information that may be backed elsewhere"""

def __init__(self, name, meta):
Expand Down Expand Up @@ -44,7 +45,7 @@ def from_dict(cls, name, d):
name (str): Attribute instance name
d (dict): Output of self.to_dict()
"""
meta = Serializable.from_dict("meta", d["meta"])
meta = Serializable.deserialize("meta", d["meta"])
attribute = cls(name, meta)
attribute.value = d["value"]
return attribute
7 changes: 4 additions & 3 deletions malcolm/core/block.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from collections import OrderedDict

from malcolm.core.notifier import Notifier
from malcolm.core.serializable import Serializable
from malcolm.core.request import Request
from malcolm.core.response import Response
Expand Down Expand Up @@ -32,8 +33,8 @@ def __exit__(self, type, value, traceback):
self.lock.acquire()
return False

@Serializable.register("malcolm:core/Block:1.0")
class Block(Serializable):
@Serializable.register_subclass("malcolm:core/Block:1.0")
class Block(Notifier):
"""Object consisting of a number of Attributes and Methods"""

def __init__(self, name):
Expand Down Expand Up @@ -94,7 +95,7 @@ def update(self, change):
# sub-structure does not exist - create and add
if len(change[0]) > 1:
raise ValueError("Missing substructure at %s" % name)
child = Serializable.from_dict(name, change[1])
child = Serializable.deserialize(name, change[1])
d = self._where_child_stored(child)
assert d is not None, \
"Change %s deserialized to unknown object %s" % (change, child)
Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/blockmeta.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from malcolm.core.meta import Meta
from malcolm.core.serializable import Serializable

@Serializable.register("malcolm:core/BlockMeta:1.0")
@Serializable.register_subclass("malcolm:core/BlockMeta:1.0")
class BlockMeta(Meta):
pass
2 changes: 1 addition & 1 deletion malcolm/core/booleanarraymeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from malcolm.core.serializable import Serializable


@Serializable.register("malcolm:core/BooleanArrayMeta:1.0")
@Serializable.register_subclass("malcolm:core/BooleanArrayMeta:1.0")
class BooleanArrayMeta(ScalarMeta):
"""Meta object containing information for a boolean array"""

Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/booleanmeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from malcolm.core.serializable import Serializable


@Serializable.register("malcolm:core/BooleanMeta:1.0")
@Serializable.register_subclass("malcolm:core/BooleanMeta:1.0")
class BooleanMeta(ScalarMeta):
"""Meta object containing information for a boolean"""

Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/choicearraymeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from malcolm.core.serializable import Serializable


@Serializable.register("malcolm:core/ChoiceArrayMeta:1.0")
@Serializable.register_subclass("malcolm:core/ChoiceArrayMeta:1.0")
class ChoiceArrayMeta(ScalarMeta):
"""Meta object containing information for a choice array"""

Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/choicemeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from malcolm.core.serializable import Serializable


@Serializable.register("malcolm:core/ChoiceMeta:1.0")
@Serializable.register_subclass("malcolm:core/ChoiceMeta:1.0")
class ChoiceMeta(ScalarMeta):
"""Meta object containing information for a enum"""

Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/clientcomms.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class ClientComms(Loggable, Spawnable):
SERVER_BLOCKS_ID=0

def __init__(self, name, process):
super(ClientComms, self).__init__(logger_name=name)
self.set_logger_name(name)
self.process = process
self.q = self.process.create_queue()
self._current_id = 1
Expand Down
3 changes: 1 addition & 2 deletions malcolm/core/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ def __init__(self, process, block):
process (Process): The process this should run under
block (Block): Block instance to add Methods and Attributes to
"""
logger_name = "%s.controller" % block.name
super(Controller, self).__init__(logger_name)
self.set_logger_name("%s.controller" % block.name)

self.writeable_methods = OrderedDict()
self.process = process
Expand Down
32 changes: 14 additions & 18 deletions malcolm/core/loggable.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,39 @@
class Loggable(object):
"""Utility class that provides a named logger for a class instance"""

def __init__(self, logger_name):
"""
Args:
logger_name (str): Name of the logger to appear in log messages
"""
super(Loggable, self).__init__()
# The name that we will pass to the logger
self._logger_name = None
# The logger object itself
self._logger = None
self.set_logger_name(logger_name)
# The actual logging logger that produces our log messages
_logger = None

def _call_log_method(self, function, msg, *arg, **kwargs):
if self._logger is None:
raise ValueError("Attempt to log to a Loggable without first calling set_logger_name()")
log_method = getattr(self._logger, function)
log_method(msg, *arg, **kwargs)

def set_logger_name(self, logger_name):
"""Change the name of the logger that log_* should call
Args:
logger_name (str): Name of the logger to appear in log messages
"""
self._logger_name = logger_name
self._logger = logging.getLogger(self._logger_name)
self._logger = logging.getLogger(logger_name)

def log_debug(self, msg, *args, **kwargs):
"""Call :meth:`logging.Logger.debug`"""
self._logger.debug(msg, *args, **kwargs)
self._call_log_method("debug", msg, *args, **kwargs)

def log_info(self, msg, *args, **kwargs):
"""Call :meth:`logging.Logger.info`"""
self._logger.info(msg, *args, **kwargs)
self._call_log_method("info", msg, *args, **kwargs)

def log_warning(self, msg, *args, **kwargs):
"""Call :meth:`logging.Logger.warning`"""
self._logger.warning(msg, *args, **kwargs)
self._call_log_method("warning", msg, *args, **kwargs)

def log_error(self, msg, *args, **kwargs):
"""Call :meth:`logging.Logger.error`"""
self._logger.error(msg, *args, **kwargs)
self._call_log_method("error", msg, *args, **kwargs)

def log_exception(self, msg, *args, **kwargs):
"""Call :meth:`logging.Logger.exception`"""
self._logger.exception(msg, *args, **kwargs)
self._call_log_method("exception", msg, *args, **kwargs)
7 changes: 4 additions & 3 deletions malcolm/core/mapmeta.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
from collections import OrderedDict

from malcolm.core.notifier import Notifier
from malcolm.core.serializable import Serializable

OPTIONAL = object()
REQUIRED = object()


@Serializable.register("malcolm:core/MapMeta:1.0")
class MapMeta(Serializable):
@Serializable.register_subclass("malcolm:core/MapMeta:1.0")
class MapMeta(Notifier):
"""An object containing a set of ScalarMeta objects"""

def __init__(self, name, description):
Expand Down Expand Up @@ -84,7 +85,7 @@ def from_dict(cls, name, d):
"""
map_meta = cls(name, d["description"])
for ename, element in d["elements"].items():
attribute_meta = Serializable.from_dict(ename, element)
attribute_meta = Serializable.deserialize(ename, element)
map_meta.add_element(attribute_meta, ename in d["required"])
map_meta.tags = d["tags"]
return map_meta
Expand Down
4 changes: 2 additions & 2 deletions malcolm/core/meta.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from collections import OrderedDict

from malcolm.core.serializable import Serializable
from malcolm.core.notifier import Notifier


class Meta(Serializable):
class Meta(Notifier):
"""Meta base class"""

def __init__(self, name, description, *args):
Expand Down
5 changes: 3 additions & 2 deletions malcolm/core/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
from inspect import getdoc

from malcolm.core.serializable import Serializable
from malcolm.core.notifier import Notifier
from malcolm.core.mapmeta import MapMeta, OPTIONAL, REQUIRED
from malcolm.core.response import Response
from malcolm.core.map import Map


@Serializable.register("malcolm:core/Method:1.0")
class Method(Serializable):
@Serializable.register_subclass("malcolm:core/Method:1.0")
class Method(Notifier):
"""Exposes a function with metadata for arguments and return values"""

def __init__(self, name, description):
Expand Down
29 changes: 29 additions & 0 deletions malcolm/core/notifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from malcolm.core.loggable import Loggable
from malcolm.core.serializable import Serializable

class Notifier(Loggable, Serializable):
def __init__(self, name):
self.name = name
self.set_logger_name(name)
self.parent = None

def set_parent(self, parent):
"""Sets the parent for changes to be propagated to"""
self.set_logger_name("%s.%s" % (parent.name, self.name))
self.parent = parent

def on_changed(self, change, notify=True):
"""Propagate change to parent, adding self.name to paths.
Args:
change: [[path], value] pair for changed values
"""
if self.parent is None:
return
path = change[0]
path.insert(0, self.name)
self.parent.on_changed(change, notify)

def set_endpoint(self, name, value, notify=True):
setattr(self, name, value)
self.on_changed([[name], value], notify)
2 changes: 1 addition & 1 deletion malcolm/core/numberarraymeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from malcolm.compat import base_string


@Serializable.register("malcolm:core/NumberArrayMeta:1.0")
@Serializable.register_subclass("malcolm:core/NumberArrayMeta:1.0")
class NumberArrayMeta(ScalarMeta):
"""Meta object containing information for an array of numerical values"""

Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/numbermeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from malcolm.compat import base_string


@Serializable.register("malcolm:core/NumberMeta:1.0")
@Serializable.register_subclass("malcolm:core/NumberMeta:1.0")
class NumberMeta(ScalarMeta):
"""Meta object containing information for a numerical value"""

Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/pointgeneratormeta.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from scanpointgenerator import CompoundGenerator


@Serializable.register("malcolm:core/PointGeneratorMeta:1.0")
@Serializable.register_subclass("malcolm:core/PointGeneratorMeta:1.0")
class PointGeneratorMeta(ScalarMeta):

def __init__(self, name, description):
Expand Down
2 changes: 1 addition & 1 deletion malcolm/core/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Process(Loggable):
"""Hosts a number of Blocks, distributing requests between them"""

def __init__(self, name, sync_factory):
super(Process, self).__init__(logger_name=name)
self.set_logger_name(name)
self.name = name
self.sync_factory = sync_factory
self.q = self.create_queue()
Expand Down

0 comments on commit d80f6f4

Please sign in to comment.