コード例 #1
0
ファイル: server.py プロジェクト: sharathrao13/DS-blog
class Server(object):
    def __init__(self):

        self.config_reader = ConfigReader('../config.ini')
        self.clock = 0

        # Config information
        self.current_server_id = int(self.config_reader.getConfiguration("CurrentServer", "sid"))
        self.total_nodes = int(self.config_reader.getConfiguration("GeneralConfig", "nodes"))
        self.peers = self.config_reader.get_peer_servers(self.current_server_id, self.total_nodes)

        # log: Each list corresponds to each node
        self.log = list()
        self.timeTable = [[0 for i in range(self.total_nodes)] for i in range(self.total_nodes)]

        # Blogs at this server
        self.blogs = list()

        # New server socket to listen to requests from Client/Peers
        self.serverSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serverSock.bind((self.config_reader.get_ip_and_port_of_server("Server" + str(self.current_server_id))))
        self.serverSock.listen(128)

    # Crux of server functionality. Main logic goes here
    def requestHandler(self, server_socket, address):

        print "New Thread..."

        msg = receiveObject(server_socket)

        if POST == msg.operation:
            # Increment clock and Insert in respective log
            self.clock += 1
            self.log.append((self.current_server_id, self.clock, msg.blog))
            self.timeTable[self.current_server_id][self.current_server_id] += 1
            self.blogs.append(msg.blog)
            self.print_data(msg, POST)


        elif LOOKUP == msg.operation:
            sendObject(server_socket, self.blogs)
            self.print_data(msg, LOOKUP)

        # Client sends the message sync so that the given server syncs with the given parameter
        elif SYNC == msg.operation:

            # all the entries where hasRec is false
            filtered_log = self.filter_log(self.log, int(msg.server_to_sync))
            message = Message(operation="server_sync", timeTable=self.timeTable, logs=filtered_log,
                              sent_server_id=self.current_server_id)

            sock_to_other = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock_to_other.connect(self.config_reader.get_ip_and_port_of_server("Server" + msg.server_to_sync))
            sendObject(sock_to_other, message)
            sock_to_other.close()

            print "Filtered Log: %s" % filtered_log
            self.print_data(msg,SYNC)

        # Received from a server. Update the logs and sync servers to complete replication
        elif SERVER_SYNC == msg.operation:

            sent_server = msg.sent_server_id
            other_log = msg.logs
            other_time_table = msg.timeTable

            self.add_new_events_to_log_and_blog(other_time_table, other_log)
            self.update_max_elements(other_time_table)
            self.update_rows(other_time_table, sent_server)
            self.print_data(msg,SERVER_SYNC)

        else:
            print "Received an unknown operation %s" % msg.operation

        server_socket.close()

    def start(self):
        # Start listening for incoming requests
        while True:
            connection, address = self.serverSock.accept()
            threading.Thread(target=self.requestHandler, args=(connection, address)).start()

    def filter_log(self, log_to_be_filtered, server_to_sync):
        
        log_to_send = []
    
        # Get the max clock values that I know that server to sync knows about blogs in other servers
        known_clocks = list()

        for i in range(self.total_nodes):
            known_clocks.append(self.timeTable[server_to_sync][i])

        log_to_send = [logEntry for logEntry in log_to_be_filtered if logEntry[1] > known_clocks[logEntry[0]]]

        return log_to_send

    def update_max_elements(self, other_time_table):
        for i in range(0, self.total_nodes):
            for j in range(0, self.total_nodes):
                self.timeTable[i][j] = max(self.timeTable[i][j], other_time_table[i][j])

    def update_rows(self, other_time_table, sent_server):
        for i in range(0, self.total_nodes):
            self.timeTable[self.current_server_id][i] = max(self.timeTable[self.current_server_id][i],
                                                            other_time_table[sent_server][i])

    def add_new_events_to_log_and_blog(self, other_time_table, other_log):
        
        # Add to Log
        log_to_append = self.filter_log(other_log, self.current_server_id)
        print "Log to append: %s" %log_to_append 
        self.log.extend(log_to_append)
    
        # Add to Dictionary
        for i in range(0, len(log_to_append)):
            self.blogs.append(log_to_append[i][2])


    def print_data(self, msg, operation):
        print "****************%s Operation***************\nLog: %s\nTT: %s\nMsg %s\nClock: %s\n" % (
        operation, self.log, self.timeTable, msg, self.clock)