Ejemplo n.º 1
0
    def Put(self, request, context):
        key = request.key
        value = request.value
        flag = request.flag
        print("Putting key.." + key)
        print("Putting value.." + value)

        self.map[key] = value

        if flag == "user":
            for host in host_list:

                #don't send it to yourself
                if host == self.ip:
                    continue

                #broadcast
                host = host + PORT
                with grpc.insecure_channel(host) as channel:
                    stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
                    print("Trying to replicate put...")

                    #TODO add try catch here
                    response = stub.Put(
                        kvstore_pb2.PutRequest(key=key,
                                               value=value,
                                               flag="server"))

        return kvstore_pb2.PutResponse(ret=kvstore_pb2.SUCCESS)
 def read_chunk(self, chunk_id, stub=None):
     if not stub:
         with grpc.insecure_channel("{}:{}".format(
                 self.KV_STORE_HOST, KV_STORE_PORT)) as channel:
             stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
             return self.__readchunk(chunk_id, stub)
     else:
         return self.__readchunk(chunk_id, stub)
 def download_file(self, dir_id, doc_id, root, flatten=False, stub=None):
     if not stub:
         with grpc.insecure_channel("{}:{}".format(
                 self.KV_STORE_HOST, KV_STORE_PORT)) as channel:
             stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
             self.__downloadfile(dir_id, doc_id, root, flatten, stub)
     else:
         self.__downloadfile(dir_id, doc_id, root, flatten, stub)
 def upload_file_str(self, dir_id, doc_id, string, stub=None):
     if not stub:
         with grpc.insecure_channel("{}:{}".format(
                 self.KV_STORE_HOST, KV_STORE_PORT)) as channel:
             stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
             self.__uploadfilestr(dir_id, doc_id, string, stub)
             channel.unsubscribe(self.close)
     else:
         self.__uploadfilestr(dir_id, doc_id, string, stub)
 def read_bytes(self, dir_id, doc_id, stub=None):
     if not stub:
         with grpc.insecure_channel("{}:{}".format(
                 self.KV_STORE_HOST, KV_STORE_PORT)) as channel:
             stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
             bytez = self.__readbytes(dir_id, doc_id, stub)
             channel.unsubscribe(self.close)
     else:
         bytez = self.__readbytes(dir_id, doc_id, stub)
     return bytez
Ejemplo n.º 6
0
def run():
    #One server test cases
    with grpc.insecure_channel(get_host()) as channel:
        stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
        print("Trying...")
        response = stub.Put(
            kvstore_pb2.PutRequest(key='a', value='b', flag='user'))
        print("Put response code: " + str(response.ret))

        response = stub.Get(kvstore_pb2.GetRequest(key='c', flag='user'))
        print("Get received code: " + str(response.ret))
        print("Get received value: " + str(response.value))
    def download_directory(self, dir_id, save_path, flatten=False, stub=None):
        log.info("Downloading directory {} at {}".format(dir_id, save_path))
        if not stub:
            with grpc.insecure_channel("{}:{}".format(
                    self.KV_STORE_HOST, KV_STORE_PORT)) as channel:
                stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
                self.__downloaddirectory(dir_id, save_path, flatten, stub)
                channel.unsubscribe(self.close)
        else:
            self.__downloaddirectory(dir_id, save_path, flatten, stub)

        log.info("Downloading directory {} at {} is successful".format(
            dir_id, save_path))
    def upload_directory(self, dirpath, stub=None):
        log.info("Uploading directory {}".format(dirpath))
        if not stub:
            with grpc.insecure_channel("{}:{}".format(
                    self.KV_STORE_HOST, KV_STORE_PORT)) as channel:
                stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
                dir_id = self.__uploaddirectory(dirpath, stub)
                channel.unsubscribe(self.close)
        else:
            dir_id = self.__uploaddirectory(dirpath, stub)

        log.info("Uploading directory {} is successful. dir_id: {}".format(
            dirpath, dir_id))
        return dir_id
Ejemplo n.º 9
0
 def thread_election(self, idx, addr, req_term):
     try:
         # Todo: shouldn't always increment term here ???
         vote_request = kvstore_pb2.VoteRequest(
             term=self.currentTerm,
             candidateID=self.id,
             lastLogIndex=self.lastLogIndex,
             lastLogTerm=req_term)
         # with grpc.insecure_channel(addr) as channel:
         channel = grpc.insecure_channel(addr)
         grpc.channel_ready_future(channel).result()
         stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
         # self.logger.debug(f'Send vote request to server: <{idx}>')
         req_vote_resp = stub.requestVote(
             vote_request,
             timeout=self.requestTimeout)  # timeout keyword ok?
         # Todo: mcip, does this improve?
         # Todo: Add lock here to consider concurrency
         if req_vote_resp.voteGranted:
             self.logger.info(
                 f'[Vote]: received from <{idx}>, vote count: <{self.numVotes}>'
             )
             if self.role == KVServer.candidate:
                 self.numVotes += 1
                 if self.numVotes >= self.majority:
                     self.role = KVServer.leader
                     with self.candidateCond:
                         # self.logger.critical(f"thread_election, larger than majority")
                         self.candidateCond.notify_all()
         else:
             self.logger.info(
                 f'[Vote]: rejected from <{idx}> its term: {req_vote_resp.term}'
             )
             # Todo: added by mcip, does this actually improve?
             if self.role == KVServer.follower and req_vote_resp.term > self.currentTerm:
                 self.save(current_term=req_vote_resp.term, voted_for=-1)
             # Todo: All servers: If RPC request or response contains term T> currentTerm, set current term = T,
             #  convert to follower
             self.convToFollowerIfHigherTerm(req_vote_resp.term,
                                             voted_for=-1)
             # self.role = KVServer.follower
             # with self.candidateCond:
             #     self.candidateCond.notify_all()
             # elif num_rej_votes > self.majority:
             #     self.save(current_term=self.currentTerm, votedFor=-1)
     except Exception as e:
         self.logger.error("[Vote]: f() thread_election:")
         self.logger.error(e)
    def download_chunk(self, chunk_id, save_path, stub=None):
        if not stub:
            with grpc.insecure_channel("{}:{}".format(
                    self.KV_STORE_HOST, KV_STORE_PORT)) as channel:
                stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
                data = self.__readchunk(chunk_id, stub)
        else:
            data = self.__readchunk(chunk_id, stub)

        if data:
            if not os.path.exists(os.path.dirname(save_path)):
                os.makedirs(os.path.dirname(save_path))

            data = data.decode(KV_STORE_ENCODING)
            with open(save_path, 'w') as f:
                f.write(data)
Ejemplo n.º 11
0
    def Get(self, request, context):

        key = request.key
        flag = request.flag

        print("Getting..." + key)
        value = ""
        found_value = False

        if key in self.map:
            value = self.map[key]
            found_value = True
        elif flag == "user":
            print("Not in this server, broadcast to all the other servers...")
            for host in host_list:
                #don't send it to yourself
                if host == self.ip:
                    continue

                #broadcast
                host = host + PORT
                with grpc.insecure_channel(host) as channel:
                    stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
                    print("Trying to broadcast get...")

                    #TODO add try catch here
                    response = stub.Get(
                        kvstore_pb2.GetRequest(key=key, flag="server"))
                    if response.ret == kvstore_pb2.SUCCESS:
                        print("Get received: " + str(response.value))
                        value = response.value
                        found_value = True
                        break

        if found_value:
            return kvstore_pb2.GetResponse(value=value,
                                           ret=kvstore_pb2.SUCCESS)
        else:
            return kvstore_pb2.GetResponse(value="", ret=kvstore_pb2.FAILURE)
Ejemplo n.º 12
0
def run():

    addresses = readAddress("remote-server.csv")
    print(addresses)

    start = time.time()
    leaderID = 0
    try:
        while True:
            if leaderID == -1:
                leaderID = 0
            channel = grpc.insecure_channel(addresses[leaderID])
            stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
            print(f'Send RegisterClient RPC to server <{leaderID}>')
            response = stub.registerClient(kvstore_pb2.RegisterRequest())
            if response.status == kvstore_pb2.OK2CLIENT:
                clientID = response.clientID
                print(f"Register client as <{clientID}>")
                break
            else:
                leaderID = response.leaderHint
                # time.sleep(0.1)
    except Exception as e:
        print(e)
    print(time.time() - start)

    # TODO: Implement PUT and GET
    myKey = "1" * 1024
    myValue = "1" * 1024
    start = time.time()
    seq_num = 1

    for i in range(100):
        try:
            while True:
                channel = grpc.insecure_channel(addresses[leaderID])
                stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
                # print("Try to put")
                response = stub.Put(
                    kvstore_pb2.PutRequest(key=myKey,
                                           value=myValue,
                                           clientID=clientID,
                                           sequenceNum=seq_num))
                if response.status == kvstore_pb2.NOT_LEADER:
                    leaderID = response.leaderHint
                elif response.status == kvstore_pb2.SESSION_EXPIRED:
                    print("Session Expired")
                elif response.status == kvstore_pb2.OK2CLIENT:
                    print("PUT OK")
                    break
                else:
                    print("PUT Error")
        except Exception as e:
            print(e)
        seq_num += 1

    print(time.time() - start)

    start = time.time()
    try:
        while True:
            channel = grpc.insecure_channel(addresses[leaderID])
            stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
            print("Try to get")
            response = stub.Get(kvstore_pb2.GetRequest(key=myKey))
            if response.status == kvstore_pb2.NOT_LEADER:
                leaderID = response.leaderHint
            elif response.status == kvstore_pb2.SESSION_EXPIRED:
                print("Session Expired")
            elif response.status == kvstore_pb2.OK2CLIENT:
                print(f'GET OK: ')  #<{response.value}>')
                break
            else:
                print("GET Error")
    except Exception as e:
        print(e)
    print(time.time() - start)
Ejemplo n.º 13
0
 def thread_append_entry(self, idx, addr, app_ent_term):
     try:
         append_request = kvstore_pb2.AppendRequest()
         append_request.term = app_ent_term  # int32 term = 1;
         append_request.leaderID = self.id  # int32 leaderID = 2;
         append_request.prevLogIndex = self.nextIndex[
             idx]  # int32 prevLogIndex = 3;
         # int32 prevLogTerm = 4;
         if 0 <= self.nextIndex[idx] < len(self.log):
             append_request.prevLogTerm = self.log[self.nextIndex[idx]][0]
         else:
             append_request.prevLogTerm = 0
         append_request.leaderCommit = self.commitIndex  # int32 leaderCommit = 6;
         last_req_log_idx = self.lastLogIndex
         self.logger.info(
             f"[AP_En]: thread_append_entry to <{idx}> prevLogInd <{append_request.prevLogIndex}> "
             f"prevLogTerm <{append_request.prevLogTerm}>")
         if self.nextIndex[idx] < len(self.log):
             for row in self.log[
                     self.
                     nextIndex[idx]:]:  # repeated LogEntry entries = 5;
                 entry = append_request.entries.add()
                 entry.term = row[0]
                 entry.key = row[1]
                 entry.val = row[2]
         self.nextIndex[
             idx] = self.lastLogIndex + 1  # Todo: should inc to +1 here?
         # with grpc.insecure_channel(addr) as channel:
         channel = grpc.insecure_channel(addr)
         grpc.channel_ready_future(channel).result()
         # int32 term = 1;
         # bool success = 2;
         stub = kvstore_pb2_grpc.KeyValueStoreStub(channel)
         if random.uniform(
                 0, 1) < self.cmserver.fail_mat[self.leaderID][self.id]:
             self.logger.warning(
                 f'[ABORTED]: we will not receive from <{self.leaderID}> '
                 f'because of ChaosMonkey')
         else:
             # self.logger.info(f'[AP_En]: thread_append_entry to <{idx}>, '
             #                  f'req last log <{last_req_log_idx}>')
             # f'req entries \n<{append_request.entries}>')
             append_entry_response = stub.appendEntries(
                 append_request, timeout=self.requestTimeout)
             if not append_entry_response.success:
                 self.logger.info(
                     f"[AP_En]: thread_append_entry to <{idx}> failed, "
                     f"its term <{append_entry_response.term}>, leader's <{self.currentTerm}>"
                 )
                 # Failed because of log inconsistency, decrement nextIndex and retry
                 if append_entry_response.term <= self.currentTerm:
                     self.logger.info(
                         f"[AP_En]: log inconsistency, nextIndex for <{idx}> dec from "
                         f"<{self.nextIndex[idx]}> to <{max(append_request.prevLogIndex - 1, 0) }>"
                     )
                     # Todo: how to decrement correctly
                     self.nextIndex[idx] = max(
                         append_request.prevLogIndex - 1, 0)
                 else:
                     # Todo: All servers: If RPC request or response contains term T> currentTerm,
                     #  set current term = T, convert to follower
                     self.convToFollowerIfHigherTerm(
                         append_entry_response.term, voted_for=-1)
             # Success
             else:
                 self.logger.info(
                     f"[AP_En]: thread_append_entry to <{idx}> success")
                 self.matchIndex[idx] = last_req_log_idx
                 self.logger.debug(
                     f'[KVStore]: matchIndex: <{self.matchIndex}>')
                 n_list = sorted(self.matchIndex)
                 # TODO: write to disk upon majority
                 # if there exists such N that N> commitIndex and majority of matchIndex[i] >= N
                 # and log[N].term ==currentTerm, set commitIndex = N
                 N = n_list[int(len(n_list) / 2)]
                 if N >= 0 and N > self.commitIndex and self.log[N][
                         0] == self.currentTerm:
                     self.commitIndex = N
                     self.logger.info(
                         f"RAFT: Commit index on leader updates to: {N}")
                     disk_write_kth = KThread(
                         target=self.applyToStateMachine,
                         args=(self.lastApplied, ))
                     disk_write_kth.start()
     except Exception as e:
         self.logger.error(
             "[Vote]: f() thread_append_entry, most likely name resolution error"
         )
         self.logger.error(e)  # Todo: Name resolution error