Loading ccnode/node.py +4 −11 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ from sjrpc.utils import ConnectionProxy, RpcHandler, threadless from ccnode import __version__ from ccnode.config import NodeConfigParser from ccnode.tags import Tag, get_tags, TagDB from ccnode.tags import Tag, get_tags, RootTagDB from ccnode.jobs import JobManager from ccnode.exc import PluginError Loading Loading @@ -210,7 +210,7 @@ class MainLoop(object): self.main_plugin = None # tag database self.tag_db = TagDB(self, tags=DEFAULT_TAGS) self.tag_db = RootTagDB(self, tags=DEFAULT_TAGS) # job manages self.job_manager = JobManager(self) Loading Loading @@ -266,7 +266,7 @@ class MainLoop(object): self.registered_plugins.add(plugin) # register tags self.tag_db.update_from_db(plugin.tag_db) plugin.tag_db.set_parent(self.tag_db) # register handler self.rpc_handler.update(plugin.rpc_handler) Loading @@ -280,14 +280,7 @@ class MainLoop(object): raise PluginError('Plugin was not registered, cannot remove') # remove tags for db_name, tag_db in plugin.tag_db: for tag_name in tag_db: del self.tag_db[db_name][tag_name] if not self.tag_db[db_name]: # if there's no more tag in the db del self.tag_db[db_name] self.tag_db.delete_from_db(plugin.tag_db) plugin.tag_db.set_parent(None) # remove handlers for handler_name in plugin.rpc_handler: Loading ccnode/plugins.py +1 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ class Base(object): self.main = kwargs.pop('loop') # plugins may define tags (see :mod:`ccnode.tags`) self.tag_db = TagDB(self.main, parent_db=self.main.tag_db) self.tag_db = TagDB() # plugins may define handler functions that would be called by the # server Loading ccnode/tags.py +145 −105 Original line number Diff line number Diff line Loading @@ -222,19 +222,17 @@ class TagDB(object): Handles common operations such as registering tag on the cc-server, updating its values, etc. TagDB can have a parent TagDB, in this case, the latter will handle tag TagDB can have a parent TagDB, in this case, the latter could handle tag registration on the cc-server. """ def __init__(self, main, parent_db=None, tags=None, sub_tags=None): def __init__(self, parent_db=None, tags=None, sub_tags=None): """ :param main: MainLoop instance :param TagDB parent_db: TagDB parent object :param iterable tags: initial tags :param dict sub_tags: initial subtags """ self.main = weakref.proxy(main) self.parent = parent_db self._parent = parent_db if tags is None: tags = tuple() Loading @@ -254,9 +252,116 @@ class TagDB(object): for tag in tags: self.add_sub_tag(sub_id, tag) def set_parent(self, parent): """Set parent tag database.""" # check if previous parent if self._parent is not None: # we must remove tags from old parent self._parent.remove_tags(self.db['__main__']) for sub_id in self.db: if sub_id == '__main__': continue self._parent.remove_sub_object(sub_id) # set new parent self._parent = parent if self._parent is not None: # add tags in new parent self._parent.add_tags(self.db['__main__'].itervalues()) for sub_id, db in self.db.iteritems(): if sub_id == '__main__': continue self._parent.add_sub_object(sub_id, db.itervalues()) # tag handling part, used by plugins def add_tags(self, tags): """ :param iterable tags: list of tags to add """ for tag in tags: self.add_tag(tag) def add_sub_tags(self, sub_id, tags): for tag in tags: self.add_sub_tag(sub_id, tag) def remove_tags(self, tag_names): """ :param iterable tag_names: list of tag names to remove """ for name in tag_names: self.remove_tag(name) def add_tag(self, tag): # set special attributes on tag instance if self._parent is not None: self._parent.add_tag(tag) self.db['__main__'][tag.name] = tag def remove_tag(self, tag_name): self.db['__main__'].pop(tag_name) if self._parent is not None: self._parent.remove_tag(tag_name) def add_sub_tag(self, sub_id, tag): if self._parent is not None: self._parent.add_sub_tag(sub_id, tag) self.db[sub_id][tag.name] = tag def remove_sub_tag(self, sub_id, tag_name): self.db[sub_id].pop(tag_name) if self._parent is not None: self._parent.remove_sub_tag(sub_id, tag_name) def add_sub_object(self, sub_id, tags): if self._parent is not None: # tags will be added after self._parent.add_sub_object(sub_id, tuple()) # add sub object tags for t in tags: self.add_sub_tag(sub_id, t) def remove_sub_object(self, sub_id): self.db.pop(sub_id) if self._parent is not None: self._parent.remove_sub_object(sub_id) # dict like def get(self, key, default=None): return self.db.get(key, default) def __getitem__(self, key): return self.db[key] def keys(self): return self.db.keys() def iteritems(self): return self.db.iteritems() def itervalues(self): return self.db.itervalues() # end dict like class RootTagDB(TagDB): """Root tag database. It takes care of tag registration with cc-server. It has no parent. """ def __init__(self, main, tags=None, sub_tags=None): """ :param main: MainLoop instance :param tags: initial tags :param sub_tags: initial sub tags """ self.main = main #: dict for async call storage, keep a part of log message self.async_calls = dict() TagDB.__init__(self, tags=tags, sub_tags=sub_tags) # RPC part def rpc_call(self, opaque, callback, remote_name, *args, **kwargs): """Local helper for all rpc calls. Loading @@ -270,6 +375,7 @@ class TagDB(object): """ # call only if connected and authenticated to the cc-server if self.main.rpc_authenticated: # logger.debug('RPC call %s %s', remote_name, args) self.async_calls[self.main.rpc_con.rpc.async_call_cb( callback, remote_name, *args, **kwargs)] = opaque Loading Loading @@ -355,122 +461,56 @@ class TagDB(object): 'Error while trying to update tag %s, %s("%s")') # end RPC part # tag handling part, used by plugins def add_tags(self, tags): """ :param iterable tags: list of tags to add """ for tag in tags: self.add_tag(tag) def add_sub_tags(self, sub_id, tags): for tag in tags: self.add_sub_tag(sub_id, tag) def remove_tags(self, tag_names): """ :param iterable tag_names: list of tag names to remove """ for name in tag_names: self.remove_tag(name) def add_tag(self, tag): # set special attributes on tag instance if self.parent is None: tag.db = self tag.sub_id = '__main__' tag.start(self.main.evloop) # register tag on the cc-server if tag.value is not None: self.rpc_register_tag(tag) else: self.parent.add_tag(tag) self.db['__main__'][tag.name] = tag def remove_tag(self, tag_name): tag = self.db['__main__'].pop(tag_name) if self.parent is None: tag.db = None tag.sub_id = None tag.stop() # unregister tag on the cc-server if tag.value is not None: self.rpc_unregister_tag(tag_name) else: self.parent.remove_tag(tag_name) def add_sub_tag(self, sub_id, tag): if self.parent is None: tag.db = self tag.sub_id = sub_id tag.start(self.main.evloop) # register tag to the cc-server if tag.value is not None: self.rpc_register_sub_tag(sub_id, tag) else: self.parent.add_sub_tag(sub_id, tag) self.db[sub_id][tag.name] = tag def remove_sub_tag(self, sub_id, tag_name): tag = self.db[sub_id].pop(tag_name) if self.parent is None: tag.db = None tag.sub_id = None tag.stop() # unregister tag to the cc-server if tag.value is not None: self.rpc_unregister_sub_tag(sub_id, tag_name) else: self.parent.remove_sub_tag(sub_id, tag_name) def add_sub_object(self, sub_id, tags): if self.parent is None: self.rpc_register_sub_object(sub_id) else: # tags will be added after self.parent.add_sub_object(sub_id, tuple()) # FIXME not sure this is needed # add sub object tags for t in tags: self.add_sub_tag(sub_id, t) def remove_sub_object(self, sub_id): if self.parent is None: for name in self.db[sub_id].keys(): self.remove_sub_tag(sub_id, name) for tag in self.db[sub_id].itervalues(): tag.stop() tag.db = None tag.sub_id = None # we don't need to unregister each sub tag on the cc-server because # it will be done when we unregister the object del self.db[sub_id] self.rpc_unregister_sub_object(sub_id) else: sub_tags = self.db.pop(sub_id) self.parent.remove_sub_object(sub_id) # dict like def get(self, key, default=None): return self.db.get(key, default) def __getitem__(self, key): return self.db[key] def keys(self): return self.db.keys() def iteritems(self): return self.db.iteritems() def itervalues(self): return self.db.itervalues() def update_from_db(self, tag_db): """Update self tag db from other instance.""" self.add_tags(tag_db['__main__'].itervalues()) for sub_id, db in tag_db.iteritems(): if sub_id == '__main__': continue self.add_sub_tags(sub_id, db.itervalues()) def delete_from_db(self, tag_db): self.remove_tags(tag_db['__main__']) for sub_id in tag_db: if sub_id == '__main__': continue self.remove_suobject(sub_id) Loading
ccnode/node.py +4 −11 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ from sjrpc.utils import ConnectionProxy, RpcHandler, threadless from ccnode import __version__ from ccnode.config import NodeConfigParser from ccnode.tags import Tag, get_tags, TagDB from ccnode.tags import Tag, get_tags, RootTagDB from ccnode.jobs import JobManager from ccnode.exc import PluginError Loading Loading @@ -210,7 +210,7 @@ class MainLoop(object): self.main_plugin = None # tag database self.tag_db = TagDB(self, tags=DEFAULT_TAGS) self.tag_db = RootTagDB(self, tags=DEFAULT_TAGS) # job manages self.job_manager = JobManager(self) Loading Loading @@ -266,7 +266,7 @@ class MainLoop(object): self.registered_plugins.add(plugin) # register tags self.tag_db.update_from_db(plugin.tag_db) plugin.tag_db.set_parent(self.tag_db) # register handler self.rpc_handler.update(plugin.rpc_handler) Loading @@ -280,14 +280,7 @@ class MainLoop(object): raise PluginError('Plugin was not registered, cannot remove') # remove tags for db_name, tag_db in plugin.tag_db: for tag_name in tag_db: del self.tag_db[db_name][tag_name] if not self.tag_db[db_name]: # if there's no more tag in the db del self.tag_db[db_name] self.tag_db.delete_from_db(plugin.tag_db) plugin.tag_db.set_parent(None) # remove handlers for handler_name in plugin.rpc_handler: Loading
ccnode/plugins.py +1 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ class Base(object): self.main = kwargs.pop('loop') # plugins may define tags (see :mod:`ccnode.tags`) self.tag_db = TagDB(self.main, parent_db=self.main.tag_db) self.tag_db = TagDB() # plugins may define handler functions that would be called by the # server Loading
ccnode/tags.py +145 −105 Original line number Diff line number Diff line Loading @@ -222,19 +222,17 @@ class TagDB(object): Handles common operations such as registering tag on the cc-server, updating its values, etc. TagDB can have a parent TagDB, in this case, the latter will handle tag TagDB can have a parent TagDB, in this case, the latter could handle tag registration on the cc-server. """ def __init__(self, main, parent_db=None, tags=None, sub_tags=None): def __init__(self, parent_db=None, tags=None, sub_tags=None): """ :param main: MainLoop instance :param TagDB parent_db: TagDB parent object :param iterable tags: initial tags :param dict sub_tags: initial subtags """ self.main = weakref.proxy(main) self.parent = parent_db self._parent = parent_db if tags is None: tags = tuple() Loading @@ -254,9 +252,116 @@ class TagDB(object): for tag in tags: self.add_sub_tag(sub_id, tag) def set_parent(self, parent): """Set parent tag database.""" # check if previous parent if self._parent is not None: # we must remove tags from old parent self._parent.remove_tags(self.db['__main__']) for sub_id in self.db: if sub_id == '__main__': continue self._parent.remove_sub_object(sub_id) # set new parent self._parent = parent if self._parent is not None: # add tags in new parent self._parent.add_tags(self.db['__main__'].itervalues()) for sub_id, db in self.db.iteritems(): if sub_id == '__main__': continue self._parent.add_sub_object(sub_id, db.itervalues()) # tag handling part, used by plugins def add_tags(self, tags): """ :param iterable tags: list of tags to add """ for tag in tags: self.add_tag(tag) def add_sub_tags(self, sub_id, tags): for tag in tags: self.add_sub_tag(sub_id, tag) def remove_tags(self, tag_names): """ :param iterable tag_names: list of tag names to remove """ for name in tag_names: self.remove_tag(name) def add_tag(self, tag): # set special attributes on tag instance if self._parent is not None: self._parent.add_tag(tag) self.db['__main__'][tag.name] = tag def remove_tag(self, tag_name): self.db['__main__'].pop(tag_name) if self._parent is not None: self._parent.remove_tag(tag_name) def add_sub_tag(self, sub_id, tag): if self._parent is not None: self._parent.add_sub_tag(sub_id, tag) self.db[sub_id][tag.name] = tag def remove_sub_tag(self, sub_id, tag_name): self.db[sub_id].pop(tag_name) if self._parent is not None: self._parent.remove_sub_tag(sub_id, tag_name) def add_sub_object(self, sub_id, tags): if self._parent is not None: # tags will be added after self._parent.add_sub_object(sub_id, tuple()) # add sub object tags for t in tags: self.add_sub_tag(sub_id, t) def remove_sub_object(self, sub_id): self.db.pop(sub_id) if self._parent is not None: self._parent.remove_sub_object(sub_id) # dict like def get(self, key, default=None): return self.db.get(key, default) def __getitem__(self, key): return self.db[key] def keys(self): return self.db.keys() def iteritems(self): return self.db.iteritems() def itervalues(self): return self.db.itervalues() # end dict like class RootTagDB(TagDB): """Root tag database. It takes care of tag registration with cc-server. It has no parent. """ def __init__(self, main, tags=None, sub_tags=None): """ :param main: MainLoop instance :param tags: initial tags :param sub_tags: initial sub tags """ self.main = main #: dict for async call storage, keep a part of log message self.async_calls = dict() TagDB.__init__(self, tags=tags, sub_tags=sub_tags) # RPC part def rpc_call(self, opaque, callback, remote_name, *args, **kwargs): """Local helper for all rpc calls. Loading @@ -270,6 +375,7 @@ class TagDB(object): """ # call only if connected and authenticated to the cc-server if self.main.rpc_authenticated: # logger.debug('RPC call %s %s', remote_name, args) self.async_calls[self.main.rpc_con.rpc.async_call_cb( callback, remote_name, *args, **kwargs)] = opaque Loading Loading @@ -355,122 +461,56 @@ class TagDB(object): 'Error while trying to update tag %s, %s("%s")') # end RPC part # tag handling part, used by plugins def add_tags(self, tags): """ :param iterable tags: list of tags to add """ for tag in tags: self.add_tag(tag) def add_sub_tags(self, sub_id, tags): for tag in tags: self.add_sub_tag(sub_id, tag) def remove_tags(self, tag_names): """ :param iterable tag_names: list of tag names to remove """ for name in tag_names: self.remove_tag(name) def add_tag(self, tag): # set special attributes on tag instance if self.parent is None: tag.db = self tag.sub_id = '__main__' tag.start(self.main.evloop) # register tag on the cc-server if tag.value is not None: self.rpc_register_tag(tag) else: self.parent.add_tag(tag) self.db['__main__'][tag.name] = tag def remove_tag(self, tag_name): tag = self.db['__main__'].pop(tag_name) if self.parent is None: tag.db = None tag.sub_id = None tag.stop() # unregister tag on the cc-server if tag.value is not None: self.rpc_unregister_tag(tag_name) else: self.parent.remove_tag(tag_name) def add_sub_tag(self, sub_id, tag): if self.parent is None: tag.db = self tag.sub_id = sub_id tag.start(self.main.evloop) # register tag to the cc-server if tag.value is not None: self.rpc_register_sub_tag(sub_id, tag) else: self.parent.add_sub_tag(sub_id, tag) self.db[sub_id][tag.name] = tag def remove_sub_tag(self, sub_id, tag_name): tag = self.db[sub_id].pop(tag_name) if self.parent is None: tag.db = None tag.sub_id = None tag.stop() # unregister tag to the cc-server if tag.value is not None: self.rpc_unregister_sub_tag(sub_id, tag_name) else: self.parent.remove_sub_tag(sub_id, tag_name) def add_sub_object(self, sub_id, tags): if self.parent is None: self.rpc_register_sub_object(sub_id) else: # tags will be added after self.parent.add_sub_object(sub_id, tuple()) # FIXME not sure this is needed # add sub object tags for t in tags: self.add_sub_tag(sub_id, t) def remove_sub_object(self, sub_id): if self.parent is None: for name in self.db[sub_id].keys(): self.remove_sub_tag(sub_id, name) for tag in self.db[sub_id].itervalues(): tag.stop() tag.db = None tag.sub_id = None # we don't need to unregister each sub tag on the cc-server because # it will be done when we unregister the object del self.db[sub_id] self.rpc_unregister_sub_object(sub_id) else: sub_tags = self.db.pop(sub_id) self.parent.remove_sub_object(sub_id) # dict like def get(self, key, default=None): return self.db.get(key, default) def __getitem__(self, key): return self.db[key] def keys(self): return self.db.keys() def iteritems(self): return self.db.iteritems() def itervalues(self): return self.db.itervalues() def update_from_db(self, tag_db): """Update self tag db from other instance.""" self.add_tags(tag_db['__main__'].itervalues()) for sub_id, db in tag_db.iteritems(): if sub_id == '__main__': continue self.add_sub_tags(sub_id, db.itervalues()) def delete_from_db(self, tag_db): self.remove_tags(tag_db['__main__']) for sub_id in tag_db: if sub_id == '__main__': continue self.remove_suobject(sub_id)