Esempio n. 1
0
    def _delete(self, path, tega_id=None, version=None):

        qname = None
        if not tega_id:
            tega_id = self.tega_id

        if isinstance(path, Cont):
            qname = path.qname_()
        else:
            qname = path2qname(path)

        if version and _collision_check(qname, version):
            raise ValueError('collision detected')
        else:

            #
            # DELETE OPERATION
            #
            #       _idb               _idb
            #       /       copy   (D) / / (E)
            #      o root(A)  o       o O ..> [Old roots]
            #    /   \   ..>   \  ..>  \
            #   o     o   (B)   o       o (C) del the attribute
            #  / \   / \                 \
            # o   o o   o             X   o
            #       ^
            #       |
            #      delete operation
            #
            root_oid = qname[0]
            prev_version, new_version, new_root, above_tail = self._copy_on_write(
                qname, above_tail=True)
            if above_tail:
                oid = qname[-1]
                instance = above_tail[oid]
                #del above_tail[oid]
                del above_tail.__dict__[oid]
                if above_tail.is_empty_():
                    above_tail.delete_()
            else:
                instance = _idb[path]

            if not root_oid in self.candidate:
                self.candidate[root_oid] = (prev_version, new_version,
                                            new_root)

            # Commit queue
            ephemeral = instance.is_ephemeral_()
            if ephemeral:
                remove_ephemeral_node(tega_id, path)
            self._enqueue_commit(OPE.DELETE, path, tega_id, instance,
                                 ephemeral)
Esempio n. 2
0
    def _notify_append(self, log):
        '''
        Appends a CRUD operation as notifications to subscribers
        '''
        path = log['path']
        instance = log['instance']
        qname = path2qname(path)

        # Searches "path" in "channels".
        # Example:
        # regex_path = 'a\.b.\c'
        for regex_path in channels:

            nested = nested_regex_path(regex_path)

            are_parents_or_me = re.match(nested + '$',
                                         path)  # (A)a.b or (B)a.b.c
            are_children = re.match(regex_path + '\.', path)  # (C)a.b.c.d

            if are_parents_or_me:
                #print(are_parents_or_me.groups())
                idx = 1
                for elm in are_parents_or_me.groups():
                    if elm:
                        idx += 1
                    else:
                        break
                sub_qname = regex_path.split('\.')[idx:]
                #print(are_parents_or_me.groups())
                #print(sub_qname)
                for regex_oid in sub_qname:
                    for oid in instance:
                        # TODO: regex matching multiple children
                        if re.match(regex_oid, oid):
                            instance = instance[oid]
                            path += '.' + oid
                        else:
                            break
                        log['path'] = path
                        log['instance'] = instance

            if are_parents_or_me or are_children:
                for subscriber in channels[regex_path]:
                    try:
                        if not subscriber in self.notify_batch:
                            self.notify_batch[subscriber] = []
                        self.notify_batch[subscriber].append(log)
                    except:
                        traceback.print_exc()
                        logging.warn(
                            'subscriber removed - {}'.format(subscriber))
                        channels[_path].remove(subscriber)
Esempio n. 3
0
File: idb.py Progetto: araobp/tega
    def _notify_append(self, log):
        '''
        Appends a CRUD operation as notifications to subscribers
        '''
        path = log['path']
        instance = log['instance']
        qname = path2qname(path)

        # Searches "path" in "channels".
        # Example:
        # regex_path = 'a\.b.\c'
        for regex_path in channels:

            nested = nested_regex_path(regex_path)
            
            are_parents_or_me = re.match(nested+'$', path) # (A)a.b or (B)a.b.c
            are_children = re.match(regex_path+'\.', path) # (C)a.b.c.d

            if are_parents_or_me:
                #print(are_parents_or_me.groups())
                idx = 1
                for elm in are_parents_or_me.groups():
                    if elm:
                        idx += 1
                    else:
                        break
                sub_qname = regex_path.split('\.')[idx:]
                #print(are_parents_or_me.groups())
                #print(sub_qname)
                for regex_oid in sub_qname:
                    for oid in instance:
                        # TODO: regex matching multiple children
                        if re.match(regex_oid, oid):
                            instance = instance[oid]
                            path += '.' + oid
                        else:
                            break
                        log['path'] = path
                        log['instance'] = instance

            if are_parents_or_me or are_children:
                for subscriber in channels[regex_path]:
                    try:
                        if not subscriber in self.notify_batch:
                            self.notify_batch[subscriber] = []
                        self.notify_batch[subscriber].append(log)
                    except:
                        traceback.print_exc()
                        logging.warn('subscriber removed - {}'.
                                format(subscriber))
                        channels[_path].remove(subscriber)
Esempio n. 4
0
File: idb.py Progetto: araobp/tega
    def _delete(self, path, tega_id=None, version=None):

        qname = None
        if not tega_id:
            tega_id = self.tega_id

        if isinstance(path, Cont):
            qname = path.qname_()
        else:
            qname = path2qname(path)

        if version and _collision_check(qname, version):
            raise ValueError('collision detected')
        else:

            #
            # DELETE OPERATION
            #
            #       _idb               _idb
            #       /       copy   (D) / / (E)
            #      o root(A)  o       o O ..> [Old roots]
            #    /   \   ..>   \  ..>  \
            #   o     o   (B)   o       o (C) del the attribute
            #  / \   / \                 \
            # o   o o   o             X   o
            #       ^
            #       |
            #      delete operation
            #
            root_oid = qname[0]
            prev_version, new_version, new_root, above_tail = self._copy_on_write(qname, above_tail=True)
            if above_tail:
                oid = qname[-1]
                instance = above_tail[oid]
                #del above_tail[oid]
                del above_tail.__dict__[oid]
                if above_tail.is_empty_():
                    above_tail.delete_()
            else:
                instance = _idb[path]

            if not root_oid in self.candidate:
                self.candidate[root_oid] = (prev_version, new_version, new_root)

            # Commit queue
            ephemeral = instance.is_ephemeral_()
            if ephemeral:
                remove_ephemeral_node(tega_id, path)
            self._enqueue_commit(OPE.DELETE, path, tega_id, instance, ephemeral)
Esempio n. 5
0
def rpc(path, args=None, kwargs=None):
    '''
    RPC (Remote Procedure Call).

    Raises KeyError if path is not found in idb.
    '''
    try:
        qname = path2qname(path)
        f = get(path)
        if type(f) == RPC:
            func = get(path)._get_func()
            if args and kwargs:
                return func(*args, **kwargs)
            elif args:
                return func(*args)
            elif kwargs:
                return func(**kwargs)
            else:
                return func()
        else:
            raise NonLocalRPC('path exists but not for local RPC')
    except KeyError:
        raise
Esempio n. 6
0
File: idb.py Progetto: araobp/tega
def rpc(path, args=None, kwargs=None):
    '''
    RPC (Remote Procedure Call).

    Raises KeyError if path is not found in idb.
    '''
    try:
        qname = path2qname(path)
        f = get(path)
        if type(f) == RPC:
            func = get(path)._get_func()
            if args and kwargs:
                return func(*args, **kwargs)
            elif args:
                return func(*args)
            elif kwargs:
                return func(**kwargs)
            else:
                return func()
        else:
            raise NonLocalRPC('path exists but not for local RPC')
    except KeyError:
        raise
Esempio n. 7
0
def get(path, version=None, regex_flag=False):
    '''
    GET operation.

    Raises KeyError if path is not found in idb.
    '''
    try:
        if regex_flag:
            regex_qname = path.split('\.')
            regex_oid = regex_qname[0]
            instances = []
            for root_oid in _idb:
                m = re.match(regex_oid, root_oid)
                if m:
                    regex_groups = []
                    g = m.groups()
                    if g:
                        regex_groups.append(g)
                    instance = _fetch_root_with_version(root_oid, version)
                    if len(regex_qname) > 1:
                        g = _select(instance, regex_qname[1:], regex_groups)
                        for match in g:
                            instances.append(match)
                    else:
                        instances.append((root_oid, instance, regex_groups))
            return instances
        else:
            qname = path2qname(path)
            root_oid = qname[0]
            instance = _fetch_root_with_version(root_oid, version)
            if len(qname) > 1:
                for oid in qname[1:]:
                    instance = instance.__dict__[oid]
            return instance
    except KeyError:
        raise
Esempio n. 8
0
File: idb.py Progetto: araobp/tega
def get(path, version=None, regex_flag=False):
    '''
    GET operation.

    Raises KeyError if path is not found in idb.
    '''
    try:
        if regex_flag:
            regex_qname = path.split('\.')
            regex_oid = regex_qname[0]
            instances = []
            for root_oid in _idb:
                m = re.match(regex_oid, root_oid)
                if m:
                    regex_groups = []
                    g = m.groups()
                    if g:
                        regex_groups.append(g)
                    instance = _fetch_root_with_version(root_oid, version)
                    if len(regex_qname) > 1:
                        g = _select(instance, regex_qname[1:], regex_groups)
                        for match in g:
                            instances.append(match)
                    else:
                        instances.append((root_oid, instance, regex_groups))
            return instances
        else:
            qname = path2qname(path)
            root_oid = qname[0]
            instance = _fetch_root_with_version(root_oid, version)
            if len(qname) > 1:
                for oid in qname[1:]:
                    instance = instance.__dict__[oid]
            return instance 
    except KeyError:
        raise