Beispiel #1
0
    def _stabilize(self):
        "Periodically verify node's inmediate succesor and tell the successor about it"
        # if successor fails find first alive successor in the
        # successor list
        if not self.is_node_alive(self.successor):
            self.successor = self.find_first_successor_alive()
            log.debug(
                f'set new succesor from successor list: {self.successor.id}')

        try:
            with self.proxy(self.successor) as remote:
                node = remote.predecessor
                if node and self.is_node_alive(node) and in_interval_r(
                        node.id, self.id, self.successor.id):
                    self.successor = node
                    log.debug(f'finded new succesor: {node.id}')
                    self._update_successor_list()
        except BaseException as why:
            pass

        try:
            with self.proxy(self.successor) as remote:
                remote.notify(self.info)
        except Pyro4.errors.ConnectionClosedError:  # between remote._update_successor_list remote fails and this is fixed when this method is called again, so i just let ignore this exception for efficiency
            pass
Beispiel #2
0
 def print_info(self):
     log.debug(f'''
     suc: {self.successor.id if self.successor else None}
     pred: {self.predecessor.id if self.predecessor else None}
     s_list: {
         list(map(lambda node: node.id if node else None,self.successor_list))}
     finger: {self.finger.print_fingers()}
     keys: {list(map(lambda i:i[0],self.data.items()))}
     assured: {list(map(lambda i:i[0],self.assured_data.items()))}''')
Beispiel #3
0
    def __init__(self, id, ip, port, chord_id: str = 'default'):
        self.id = id
        self.ip = ip
        self.port = port
        self.finger = FingerTable(self.id)
        self.data = {}
        self._successor_list = [None for _ in range(m)]
        self.assured_data = {}
        self.chord_id = chord_id

        log.init_logger(f"Node {self.id}", log.INFO)  # init logging
        log.debug(f"init")
Beispiel #4
0
 def inner(*args, **kwargs):
     for i in range(attempts):
         try:
             result = func(*args, **kwargs)
         except BaseException as error:
             log.error(
                 f'retry {i+1}/{attempts} {func.__name__}:  {error}')
             time.sleep(retry_delay)
             continue
         if i > 0:
             log.debug(
                 f'resolve correctly function: {func.__name__} in attemt {i}'
             )
         return result
     log.exception(f"can't handle exceptions with stabilization")
     args[0].print_info()
Beispiel #5
0
    def notify(self, node: 'NodeInfo'):
        "Node think is might be our predecessor"
        if not self.predecessor or not self.is_node_alive(
                self.predecessor) or in_interval(node.id, self.predecessor.id,
                                                 self.id):
            self.predecessor = node
            log.debug(f'set new predecessor: {node.id}')

            # Take dada from storage is needed
            for key in list(self.assured_data.keys()):
                if in_interval(key, self.predecessor.id, self.id):
                    value, t = self.assured_data.pop(key)
                    self.data[key] = value
                    log.debug(f'assume key assured : {key}')
            # Transfer data to predecessor
            transference = {}
            for key in list(self.data.keys()):
                # this interval is all the rign except this node
                # interval, is different of key < predecessor.id
                # because the rign is circular
                if in_interval(key, self.id, self.predecessor.id):
                    transference[key] = self.data.pop(key)
            # send data to predecessor node
            try:
                with self.proxy(self.predecessor) as remote:
                    remote.set_data(transference)
                    log.debug(
                        f'set data to predecessor (node {self.predecessor.id}): {list(transference.keys())}'
                    )
            except BaseException:
                log.exception(
                    f'problem sending data to node {self.predecessor.id}')
                # remerge data again into this node data
                self.data = {**self.data, **transference}
Beispiel #6
0
 def join(self, node: 'NodeInfo'):
     "node self joins the network node is a arbitrary node in the network"
     self.predecessor = None
     log.debug('joint')
     with self.proxy(node) as remote:
         self.successor = remote.find_successor(self.id)
         # initialize successor_list using successor.successor_list
         log.debug(f'finded successor: {self.successor.id}')
         self._update_successor_list()
     log.debug(f"join to {node.id} succesfuly")
Beispiel #7
0
 def delete(self, key):
     log.debug(f"call delete key {key}")
     node = self.find_successor(key)
     with self.proxy(node) as remote:
         return remote.delete_item(key)
Beispiel #8
0
 def load(self, key):
     log.debug(f"call load key {key}")
     node = self.find_successor(key)
     with self.proxy(node) as remote:
         return remote.get_item(key)
Beispiel #9
0
 def save(self, key: int, value):
     log.debug(f"call save key: {key}")
     node = self.find_successor(key)
     with self.proxy(node) as remote:
         remote.set_item(key, value)
Beispiel #10
0
 def __del__(self):
     self.pyro_daemon.close()
     log.debug('shutdown')