diff --git a/secop/modules.py b/secop/modules.py index 20eacc6..e6c7a7b 100644 --- a/secop/modules.py +++ b/secop/modules.py @@ -189,21 +189,21 @@ class Module(object): v.unit = v.unit.replace('$', self.accessibles['value'].unit) - def init(self): + def early_init(self): # may be overriden in derived classes to init stuff - self.log.debug('empty init()') + self.log.debug('empty early_init()') - def postinit(self): - self.log.debug('empty postinit()') + def init_module(self): + self.log.debug('empty init_module()') - def late_init(self, started_callback): - '''runs after postinit of all modules + def start_module(self, started_callback): + '''runs after init of all modules started_callback to be called when thread spawned by late_init or, if not implmemented, immediately ''' - self.log.debug('empty late init()') + self.log.debug('empty start_module()') started_callback(self) @@ -238,10 +238,7 @@ class Readable(Module): ), } - def init(self): - Module.init(self) - - def late_init(self, started_callback): + def start_module(self, started_callback): '''start polling thread''' mkthread(self.__pollThread, started_callback) diff --git a/secop/server.py b/secop/server.py index 4bd4de6..66fe208 100644 --- a/secop/server.py +++ b/secop/server.py @@ -214,16 +214,16 @@ class Server(object): for devname, devobj, export in devs: self.log.info(u'registering module %r' % devname) self._dispatcher.register_module(devobj, devname, export) - # also call init on the modules - devobj.init() - # call postinit on each module after registering all + # also call early_init on the modules + devobj.early_init() + # call init on each module after registering all for _devname, devobj, _export in devs: - devobj.postinit() + devobj.init_module() starting_modules = set() finished_modules = Queue() for _devname, devobj, _export in devs: starting_modules.add(devobj) - devobj.late_init(started_callback=finished_modules.put) + devobj.start_module(started_callback=finished_modules.put) # remark: it is the module implementors responsibility to call started_callback # within reasonable time (using timeouts). If we find later, that this is not # enough, we might insert checking for a timeout here, and somehow set the remaining @@ -233,6 +233,7 @@ class Server(object): self.log.info(u'%s has started' % finished.name) # use discard instead of remove here, catching the case when started_callback is called twice starting_modules.discard(finished) + finished_modules.task_done() def _processInterfaceOptions(self, interfaceopts): # eval interfaces diff --git a/secop/simulation.py b/secop/simulation.py index e956885..6ae0a8e 100644 --- a/secop/simulation.py +++ b/secop/simulation.py @@ -55,7 +55,7 @@ class SimBase(object): return newval setattr(self, 'write_' + k, writer) - def late_init(self): + def init_module(self): self._sim_thread = mkthread(self._sim) def _sim(self): diff --git a/secop_demo/cryo.py b/secop_demo/cryo.py index 77a30af..29b4ba5 100644 --- a/secop_demo/cryo.py +++ b/secop_demo/cryo.py @@ -129,7 +129,7 @@ class Cryostat(CryoBase): None), ) - def init(self): + def init_module(self): self._stopflag = False self._thread = mkthread(self.thread) diff --git a/secop_demo/modules.py b/secop_demo/modules.py index 96db9eb..6c01afe 100644 --- a/secop_demo/modules.py +++ b/secop_demo/modules.py @@ -115,7 +115,7 @@ class MagneticField(Drivable): ), } - def init(self): + def init_module(self): self._state = Enum('state', idle=1, switch_on=2, switch_off=3, ramp=4).idle self._heatswitch = self.DISPATCHER.get_module(self.heatswitch) _thread = threading.Thread(target=self._thread) @@ -211,7 +211,7 @@ class SampleTemp(Drivable): ), } - def init(self): + def init_module(self): _thread = threading.Thread(target=self._thread) _thread.daemon = True _thread.start() diff --git a/secop_mlz/amagnet.py b/secop_mlz/amagnet.py index 3592666..720b325 100644 --- a/secop_mlz/amagnet.py +++ b/secop_mlz/amagnet.py @@ -132,8 +132,8 @@ class GarfieldMagnet(SequencerMixin, Drivable): raise ConfigError(self, '_current2field polynome not monotonic!') - def init(self): - super(GarfieldMagnet, self).init() + def init_module(self): + super(GarfieldMagnet, self).init_module() self._enable = self.DISPATCHER.get_module(self.subdev_enable) self._symmetry = self.DISPATCHER.get_module(self.subdev_symmetry) self._polswitch = self.DISPATCHER.get_module(self.subdev_polswitch) diff --git a/secop_mlz/entangle.py b/secop_mlz/entangle.py index fe2cc0d..d9ab607 100644 --- a/secop_mlz/entangle.py +++ b/secop_mlz/entangle.py @@ -210,12 +210,12 @@ class PyTangoDevice(Module): self._com_warn(tries, name, err, info) sleep(self.comdelay) - def init(self): + def early_init(self): # Wrap PyTango client creation (so even for the ctor, logging and # exception mapping is enabled). self._createPyTangoDevice = self._applyGuardToFunc( self._createPyTangoDevice, 'constructor') - super(PyTangoDevice, self).init() + super(PyTangoDevice, self).early_init() @lazy_property def _dev(self): @@ -379,8 +379,8 @@ class AnalogInput(PyTangoDevice, Readable): The AnalogInput handles all devices only delivering an analogue value. """ - def late_init(self, started_callback): - super(AnalogInput, self).late_init(started_callback) + def start_module(self, started_callback): + super(AnalogInput, self).start_module(started_callback) # query unit from tango and update value property attrInfo = self._dev.attribute_query('value') # prefer configured unit if nothing is set on the Tango device, else @@ -456,14 +456,14 @@ class AnalogOutput(PyTangoDevice, Drivable): _timeout = None _moving = False - def init(self): - super(AnalogOutput, self).init() + def init_module(self): + super(AnalogOutput, self).init_module() # init history self._history = [] # will keep (timestamp, value) tuple self._timeout = None # keeps the time at which we will timeout, or None - def late_init(self, started_callback): - super(AnalogOutput, self).late_init(started_callback) + def start_module(self, started_callback): + super(AnalogOutput, self).start_module(started_callback) # query unit from tango and update value property attrInfo = self._dev.attribute_query('value') # prefer configured unit if nothing is set on the Tango device, else @@ -801,8 +801,8 @@ class NamedDigitalInput(DigitalInput): datatype=StringType(), export=False), # XXX:!!! } - def init(self): - super(NamedDigitalInput, self).init() + def init_module(self): + super(NamedDigitalInput, self).init_module() try: # pylint: disable=eval-used self.accessibles['value'].datatype = EnumType('value', **eval(self.mapping)) @@ -826,8 +826,8 @@ class PartialDigitalInput(NamedDigitalInput): datatype=IntRange(0), default=1), } - def init(self): - super(PartialDigitalInput, self).init() + def init_module(self): + super(PartialDigitalInput, self).init_module() self._mask = (1 << self.bitwidth) - 1 # self.accessibles['value'].datatype = IntRange(0, self._mask) @@ -868,8 +868,8 @@ class NamedDigitalOutput(DigitalOutput): datatype=StringType(), export=False), } - def init(self): - super(NamedDigitalOutput, self).init() + def init_module(self): + super(NamedDigitalOutput, self).init_module() try: # pylint: disable=eval-used self.accessibles['value'].datatype = EnumType('value', **eval(self.mapping)) @@ -896,8 +896,8 @@ class PartialDigitalOutput(NamedDigitalOutput): datatype=IntRange(0), default=1), } - def init(self): - super(PartialDigitalOutput, self).init() + def init_module(self): + super(PartialDigitalOutput, self).init_module() self._mask = (1 << self.bitwidth) - 1 # self.accessibles['value'].datatype = IntRange(0, self._mask) # self.accessibles['target'].datatype = IntRange(0, self._mask) diff --git a/test/test_modules.py b/test/test_modules.py index 014dd7c..da83093 100644 --- a/test/test_modules.py +++ b/test/test_modules.py @@ -28,6 +28,10 @@ sys.path.insert(0, sys.path[0] + '/..') # no fixtures needed import pytest +try: + import Queue as queue +except ImportError: + import queue as queue from secop.datatypes import BoolType, EnumType @@ -47,7 +51,11 @@ def test_Communicator(): ))() o = Communicator(logger, {}, 'o1', dispatcher) - o.init() + o.early_init() + o.init_module() + q = queue.Queue() + o.start_module(q.put) + q.get() def test_ModuleMeta(): newclass = ModuleMeta.__new__(ModuleMeta, 'TestReadable', (Drivable, Writable, Readable, Module), { @@ -100,5 +108,10 @@ def test_ModuleMeta(): params_found.add(o) assert o.ctr not in ctr_found ctr_found.add(o.ctr) - o1.init() - o2.init() + o1.early_init() + o2.early_init() + o1.init_module() + o2.init_module() + q = queue.Queue() + o1.start_module(q.put) + o2.start_module(q.put) diff --git a/test/test_blubb.py b/test/test_test.py similarity index 100% rename from test/test_blubb.py rename to test/test_test.py