def _select(self):
     primary_id = self.id
     for mate in self.mates:
         with grpc.insecure_channel(
                 '{}:{}'.format(self.mates[mate]['ip'],
                                self.mates[mate]['port'])) as channel:
             stub = ChunkServer_pb2_grpc.ChunkServerStub(channel)
             response = stub.select_primary(
                 ChunkServer_pb2.Secondary(id=self.id,
                                           ip=self.ip,
                                           port=self.port))
             if response.id != self.id:
                 primary_id = response.id
                 break
     if primary_id == self.id:
         self.role = 'primary'
         for mate in self.mates:
             with grpc.insecure_channel('{}:{}'.format(
                     self.mates[mate]['ip'],
                     self.mates[mate]['port'])) as channel:
                 stub = ChunkServer_pb2_grpc.ChunkServerStub(channel)
                 stub.replace_primary(
                     ChunkServer_pb2.Primary(id=self.id,
                                             ip=self.ip,
                                             port=self.port))
         with grpc.insecure_channel('{}:{}'.format(
                 self.master_ip, self.master_port)) as channel:
             stub = MasterServer_pb2_grpc.MasterServerStub(channel)
             stub.replace_chunk(
                 MasterServer_pb2.Replace(old_chunk=MasterServer_pb2.Chunk(
                     id=self.primary_id,
                     ip=self.primary_ip,
                     port=self.primary_port),
                                          new_chunk=MasterServer_pb2.Chunk(
                                              id=self.id,
                                              ip=self.ip,
                                              port=self.port,
                                              num_keys=len(self.table))))
 def __init__(self,
              id,
              ip,
              port,
              master_ip,
              master_port,
              role='primary',
              primary_id=None,
              primary_ip=None,
              primary_port=None):
     self.id = id
     self.ip = ip
     self.port = port
     self.role = role
     self.master_ip = master_ip
     self.master_port = master_port
     self.master_status = True
     self.primary_id = primary_id
     self.primary_ip = primary_ip
     self.primary_port = primary_port
     self.secondaries = {}
     self.mates = {}
     self.table = {}  # id:{value:...,type:...}
     self.secondaries_lock = threading.Lock()
     self.table_lock = threading.Lock()
     self.mates_lock = threading.Lock()
     if self.role == 'primary':
         if os.path.exists(settings.Table_File):
             with open(settings.Table_File, 'r') as file:
                 self.table = json.load(file)
         else:
             with grpc.insecure_channel('{}:{}'.format(
                     self.master_ip, self.master_port)) as channel:
                 stub = MasterServer_pb2_grpc.MasterServerStub(channel)
                 response = stub.add_chunk(
                     MasterServer_pb2.Chunk(id=self.id,
                                            ip=self.ip,
                                            port=self.port,
                                            num_keys=len(self.table)))
                 if response.code != 200:
                     print('error: {}'.format(response.msg))
                     r = input('Replace the existed chunk? (y or n)')
                     if r == 'y':
                         response = stub.replace_chunk(
                             MasterServer_pb2.Replace(
                                 old_chunk=MasterServer_pb2.Chunk(
                                     id=self.id),
                                 new_chunk=MasterServer_pb2.Chunk(
                                     id=self.id,
                                     ip=self.ip,
                                     port=self.port,
                                     num_keys=len(self.table))))
                         if response.code != 200:
                             print('add chunk failed, error: {}'.format(
                                 response.msg))
                             exit(0)
                     else:
                         exit(0)
     else:
         with grpc.insecure_channel('{}:{}'.format(
                 self.primary_ip, self.primary_port)) as channel:
             stub = ChunkServer_pb2_grpc.ChunkServerStub(channel)
             response = stub.sync_tables(ChunkServer_pb2.Empty())
             for item in response:
                 self.table[item.key] = {
                     'value': item.value,
                     'type': item.type
                 }
             response = stub.sync_mates(ChunkServer_pb2.Empty())
             for mate in response:
                 self.mates[mate.id] = {'ip': mate.ip, 'port': mate.port}
             response = stub.add_secondary(
                 ChunkServer_pb2.Secondary(id=self.id,
                                           ip=self.ip,
                                           port=self.port))
             if response.code != 200:
                 print('error: {}'.format(response.msg))
                 exit(0)