Пример #1
0
def AppendEntries(command, cluster_node):
    # AppendEntries(<index>, !<var>) or AppendEntries(<index>, <var>, <value>)
    log = open("log.txt", 'r+')
    params = command.getParams()

    # Need to make sure that the commit index is the same as the leader
    if cluster_node.commit_index != int(params[0]):
        # Replicate log and set commit_index
        return parse.Command("print", ["Failed!"])

    # Copy file contents into a string
    contents = ""
    for line in log:
        contents = contents + line

    # If it should return a value at a specific <var>
    if command.shouldReturnVal():
        # Find start and end indexes for <value>
        if params[1] not in contents:
            return parse.Command("print", ["Failed!"])

        index = contents.find(params[1])
        var = contents[index:index + len(params[1])]

        start_index = index + len(params[1]) + 1
        temp = contents[start_index:len(contents)]

        end_index = temp.index('\n') + start_index
        val = contents[start_index:end_index]

        return parse.Command("print", [val])

    else:
        # New value to be added to the beginning of the file
        # Edit string and write to the file
        cluster_node.commit_index += 1

        new_contents = params[1] + ':' + params[2] + '\n'

        for i in range(0, len(contents)):
            new_contents = new_contents + contents[i]

        try:
            log.truncate(0)
            log.write(new_contents)
            log.close()

        except IOError:
            if command.getCommand() == "LeaderAppend":
                return parse.Command("print", ["Failed!"])

    if command.getCommand() == "LeaderAppend":
        return parse.Command("print", ["Success!"])
Пример #2
0
    def receiveFromClient(self, conn, addr):
        threading.Thread(target=self.quitThread, args=(conn,)).start()

        while not self.shouldEnd:
            # Get command from follower/client
            command = parse.Command(None, None, None)
            try:
                data = conn.recv(self.cluster_node.BUFFER_SIZE)
                if not data: continue

                command = pickle.loads(data)
            except:
                break

            # Returns something to be printed on both leader and followers
            ret_cmd = process.processCommand(command, self.cluster_node, addr)

            if ret_cmd:
                print(ret_cmd.getParams()[0])
                conn.send(pickle.dumps(ret_cmd))

            # Once leader has finished the operation, all followers must do the same (as long as it is not a retrieval)
            if not command.shouldReturnVal():
                self.cluster_node.broadcast(command)

        conn.close()
        self.cluster_node.followers.remove(conn)
Пример #3
0
def dumpLog(command, cluster_node):
    # dumpLog(<id>)
    id = command.getParams()[0]

    original_id = ""
    if len(command.getParams()) == 1:
        command.addParam(cluster_node.IP)
        original_id = cluster_node.IP
    else:
        original_id = command.getParams()[1]

    if id == cluster_node.IP:
        log = open("log.txt", 'r')
        contents = "\n\tMOST RECENT INDEX (TOP)\n"

        for line in log:
            contents += line

        contents += "\n\tOLDEST INDEX (BOTTOM)\n"

        return parse.Command("print", [contents, original_id])

    elif cluster_node.isLeader():
        isFollower = False

        for ip in cluster_node.follower_ips:
            if ip == id:
                isFollower = True

        if isFollower:
            logRequest = parse.Command("LogRequest", [id, original_id])
            cluster_node.broadcast(logRequest)

            return None
        else:
            return parse.Command("print", ["Failed!"])
    else:
        return None
Пример #4
0
def ClientCommit(command, cluster_node):
    # ClienCommit(!<var>) or ClientCommit(<var>, <value>)
    # Process parameters

    params = command.getParams()
    if command.shouldReturnVal():
        # Broadcast
        read_entry = parse.Command("AppendEntries",
                                   [cluster_node.commit_index, params[0]],
                                   True)
        return AppendEntries(read_entry, cluster_node)
    elif cluster_node.isLeader():
        new_entry = parse.Command(
            "AppendEntries", [cluster_node.commit_index, params[0], params[1]])

        cluster_node.broadcast(new_entry)
        new_entry = parse.Command(
            "LeaderAppend", [cluster_node.commit_index, params[0], params[1]])

        return AppendEntries(new_entry, cluster_node)

    else:
        return None
Пример #5
0
    def run(self):

        # Initialize incoming TCP connections
        self.s.bind((self.cluster_node.IP, self.cluster_node.port))
        self.cluster_node.port = self.s.getsockname()[1]
        self.s.listen(5) # number of connections to server

        print("Connection IP address: ", self.cluster_node.IP)
        print("Connection opened on port: ", self.s.getsockname()[1])

        # Handles new connections until it should end
        while not self.shouldEnd:
            # Accept connection
            conn, addr = self.s.accept()
            print("Connection from address:", addr)

            # Log replication for new followers
            log = open("log.txt", 'r')
            contents = ""
            for line in log:
                contents += line
            log.close()

            conn.send(pickle.dumps(parse.Command("log", [contents, str(self.cluster_node.commit_index)])))

            # Append new follower to followers
            self.cluster_node.followers.append(conn)

            # Handles adding clients and receiving messages
            add_client_thread = threading.Thread(target=self.receiveFromClient, args=(conn, addr))

            add_client_thread.start()


        add_client_thread.join()
        conn.close()
        print("Connection closed")
Пример #6
0
    def run(self):
        print("gets here")
        self.s.bind((self.cluster_node.IP, self.cluster_node.port))

        election_cmd = parse.Command("election", self.IP, False)
        self.cluster_node.broadcast(election_cmd)
Пример #7
0
 def write_init(self):
     self.f.write(BOOTSTRAP_SP)
     init_cmd = parse.Command("call Sys.init 0")
     self.write_call(init_cmd)
Пример #8
0
 def heartbeatTimer(self):
     heartbeat_cmd = parse.Command("heartbeat", self.cluster_node.follower_ips)
     while not self.shouldEnd:
         time.sleep(30) # should be 30 seconds
         self.cluster_node.broadcast(heartbeat_cmd)