Loading cloudcontrol/common/client/tags.py +77 −15 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ from functools import partial, wraps from itertools import chain from collections import defaultdict from cloudcontrol.common.client.exc import TagConflict logger = logging.getLogger(__name__) Loading Loading @@ -257,7 +259,7 @@ class TagDB(object): for tag in tags: self.add_sub_tag(sub_id, tag) def set_parent(self, parent): def set_parent(self, parent, ignore_errors=False): """Set parent tag database.""" # check if previous parent if self._parent is not None: Loading @@ -271,7 +273,8 @@ class TagDB(object): self._parent = parent if self._parent is not None: # add tags in new parent self._parent.add_tags(self.db['__main__'].itervalues()) self._parent.add_tags(self.db['__main__'].itervalues(), ignore_errors) for sub_id, db in self.db.iteritems(): if sub_id == '__main__': Loading @@ -280,16 +283,30 @@ class TagDB(object): self._object_types[sub_id]) # tag handling part, used by plugins def add_tags(self, tags): def add_tags(self, tags, ignore_errors=False): """ :param iterable tags: list of tags to add """ for tag in tags: try: self.add_tag(tag) def add_sub_tags(self, sub_id, tags): except TagConflict as exc: if not ignore_errors: raise # else logger.warning('Ignoring error %s while adding tag %s', exc, tag.name) def add_sub_tags(self, sub_id, tags, ignore_errors=False): for tag in tags: try: self.add_sub_tag(sub_id, tag) except TagConflict as exc: if not ignore_errors: raise # else logger.warning('Ignoring error %s while adding tag %s (%s)', exc, tag.name, sub_id) def remove_tags(self, tag_names): """ Loading @@ -298,25 +315,45 @@ class TagDB(object): for name in tag_names: self.remove_tag(name) def check_tag(self, tag): """Checks that a given tag object is the same instance in the db Usefull for checking before removing. """ return id(self.db['__main__'].get(tag.name, None)) == id(tag) def add_tag(self, tag): if tag.name in self.db['__main__']: raise TagConflict('A tag with the same name is already registered') # first add the tag to the child db, in case of conflict in the parent, # the tag is recorded in the child thus if the latter's parent is # changed it can be recorded again after self.db['__main__'][tag.name] = 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: tag = self.db['__main__'].pop(tag_name) if self._parent is not None and self._parent.check_tag(tag): # remove tag in parent db only if it is the same instance self._parent.remove_tag(tag_name) def check_sub_tag(self, sub_id, tag): return id(self.db[sub_id].get(tag.name, None)) == id(tag) def add_sub_tag(self, sub_id, tag): if tag.name in self.db[sub_id]: raise TagConflict('A tag with the same name is already registered') self.db[sub_id][tag.name] = 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: tag = self.db[sub_id].pop(tag_name) if self._parent is not None and self._parent.check_tag(tag): self._parent.remove_sub_tag(sub_id, tag_name) def add_sub_object(self, sub_id, tags, type_): Loading Loading @@ -357,11 +394,27 @@ def thread_check(func): @wraps(func) def decorated(self, *args, **kwargs): if threading.current_thread() is self.pyev_thread: # if called from main thread, don't do anything special return func(self, *args, **kwargs) else: self.queue.put(partial(func, self, *args, **kwargs)) exc = None return_value = None event = threading.Event() def cb(): try: return_value = func(self, *args, **kwargs) except Exception as e: exc = e finally: event.set() self.queue.put(cb) self.async.send() # return None # wait for tag to be processed and raise error event.wait() if exc is not None: raise exc return return_value return decorated Loading Loading @@ -507,6 +560,10 @@ class RootTagDB(TagDB): @thread_check def add_tag(self, tag): if tag.name in self.db['__main__']: raise TagConflict( 'A tag with the name %s was already registered' % tag.name) # set special attributes on tag instance tag.db = self tag.sub_id = '__main__' Loading @@ -528,6 +585,11 @@ class RootTagDB(TagDB): @thread_check def add_sub_tag(self, sub_id, tag): if tag.name in self.db[sub_id]: raise TagConflict( 'A tag with the name %s (%s) was already registered' % (tag.name, sub_id)) tag.db = self tag.sub_id = sub_id tag.start(self.main.evloop) Loading Loading
cloudcontrol/common/client/tags.py +77 −15 Original line number Diff line number Diff line Loading @@ -7,6 +7,8 @@ from functools import partial, wraps from itertools import chain from collections import defaultdict from cloudcontrol.common.client.exc import TagConflict logger = logging.getLogger(__name__) Loading Loading @@ -257,7 +259,7 @@ class TagDB(object): for tag in tags: self.add_sub_tag(sub_id, tag) def set_parent(self, parent): def set_parent(self, parent, ignore_errors=False): """Set parent tag database.""" # check if previous parent if self._parent is not None: Loading @@ -271,7 +273,8 @@ class TagDB(object): self._parent = parent if self._parent is not None: # add tags in new parent self._parent.add_tags(self.db['__main__'].itervalues()) self._parent.add_tags(self.db['__main__'].itervalues(), ignore_errors) for sub_id, db in self.db.iteritems(): if sub_id == '__main__': Loading @@ -280,16 +283,30 @@ class TagDB(object): self._object_types[sub_id]) # tag handling part, used by plugins def add_tags(self, tags): def add_tags(self, tags, ignore_errors=False): """ :param iterable tags: list of tags to add """ for tag in tags: try: self.add_tag(tag) def add_sub_tags(self, sub_id, tags): except TagConflict as exc: if not ignore_errors: raise # else logger.warning('Ignoring error %s while adding tag %s', exc, tag.name) def add_sub_tags(self, sub_id, tags, ignore_errors=False): for tag in tags: try: self.add_sub_tag(sub_id, tag) except TagConflict as exc: if not ignore_errors: raise # else logger.warning('Ignoring error %s while adding tag %s (%s)', exc, tag.name, sub_id) def remove_tags(self, tag_names): """ Loading @@ -298,25 +315,45 @@ class TagDB(object): for name in tag_names: self.remove_tag(name) def check_tag(self, tag): """Checks that a given tag object is the same instance in the db Usefull for checking before removing. """ return id(self.db['__main__'].get(tag.name, None)) == id(tag) def add_tag(self, tag): if tag.name in self.db['__main__']: raise TagConflict('A tag with the same name is already registered') # first add the tag to the child db, in case of conflict in the parent, # the tag is recorded in the child thus if the latter's parent is # changed it can be recorded again after self.db['__main__'][tag.name] = 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: tag = self.db['__main__'].pop(tag_name) if self._parent is not None and self._parent.check_tag(tag): # remove tag in parent db only if it is the same instance self._parent.remove_tag(tag_name) def check_sub_tag(self, sub_id, tag): return id(self.db[sub_id].get(tag.name, None)) == id(tag) def add_sub_tag(self, sub_id, tag): if tag.name in self.db[sub_id]: raise TagConflict('A tag with the same name is already registered') self.db[sub_id][tag.name] = 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: tag = self.db[sub_id].pop(tag_name) if self._parent is not None and self._parent.check_tag(tag): self._parent.remove_sub_tag(sub_id, tag_name) def add_sub_object(self, sub_id, tags, type_): Loading Loading @@ -357,11 +394,27 @@ def thread_check(func): @wraps(func) def decorated(self, *args, **kwargs): if threading.current_thread() is self.pyev_thread: # if called from main thread, don't do anything special return func(self, *args, **kwargs) else: self.queue.put(partial(func, self, *args, **kwargs)) exc = None return_value = None event = threading.Event() def cb(): try: return_value = func(self, *args, **kwargs) except Exception as e: exc = e finally: event.set() self.queue.put(cb) self.async.send() # return None # wait for tag to be processed and raise error event.wait() if exc is not None: raise exc return return_value return decorated Loading Loading @@ -507,6 +560,10 @@ class RootTagDB(TagDB): @thread_check def add_tag(self, tag): if tag.name in self.db['__main__']: raise TagConflict( 'A tag with the name %s was already registered' % tag.name) # set special attributes on tag instance tag.db = self tag.sub_id = '__main__' Loading @@ -528,6 +585,11 @@ class RootTagDB(TagDB): @thread_check def add_sub_tag(self, sub_id, tag): if tag.name in self.db[sub_id]: raise TagConflict( 'A tag with the name %s (%s) was already registered' % (tag.name, sub_id)) tag.db = self tag.sub_id = sub_id tag.start(self.main.evloop) Loading