Beispiel #1
0
    def __init__(self,
                 nodetype,
                 addr=args.addr,
                 port=args.port,
                 givenbootstraplist=args.bootstrap,
                 debugoption=args.debug,
                 objectname=args.objectname,
                 instantiateobj=False,
                 configpath=args.configpath,
                 logger=args.logger,
                 writetodisk=args.writetodisk):
        self.addr = addr if addr else findOwnIP()
        self.port = port
        self.type = nodetype
        self.debug = debugoption
        self.durable = writetodisk
        if instantiateobj:
            if objectname == '':
                parser.print_help()
                self._graceexit(1)
            self.objectname = objectname
        # initialize receive queue
        self.receivedmessages_semaphore = Semaphore(0)
        self.receivedmessages = []
        # lock to synchronize message handling
        self.lock = Lock()
        # create server socket and bind to a port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.socket.setblocking(0)
        if self.port:
            try:
                self.socket.bind((self.addr,self.port))
            except socket.error as e:
                print "Cannot bind to port %d" % self.port
                print "Socket Error: ", e
                self._graceexit(1)
        else:
            for i in range(50):
                self.port = random.randint(14000,15000)
                try:
                    self.socket.bind((self.addr,self.port))
                    break
                except socket.error as e:
                    print "Socket Error: ", e
                    pass
        self.socket.listen(10)
        self.connectionpool = ConnectionPool()
        try:
            self.connectionpool.epoll = select.epoll()
        except AttributeError as e:
            # the os doesn't support epoll
            self.connectionpool.epoll = None
        self.alive = True
        self.me = Peer(self.addr,self.port,self.type)
        # set id
        self.id = '%s:%d' % (self.addr, self.port)

        # set path for additional configuration data
        self.configpath = configpath
        # set the logger
        try:
            LOGGERNODE = load_configdict(self.configpath)['LOGGERNODE']
        except KeyError as e:
            if logger:
                LOGGERNODE=logger
            else:
                LOGGERNODE = None
        self.logger = Logger("%s-%s" % (node_names[self.type],self.id), lognode=LOGGERNODE)
        print "%s-%s connected." % (node_names[self.type],self.id)
        # Initialize groups
        # Keeps {peer:outofreachcount}
        self.replicas = {}
        self.acceptors = {}
        self.nameservers = {}
        self.groups = {NODE_REPLICA: self.replicas,
                       NODE_ACCEPTOR: self.acceptors,
                       NODE_NAMESERVER: self.nameservers}
        self.groups[self.me.type][self.me] = 0

        # Keeps the liveness of the nodes
        self.nodeliveness = {}
        # connect to the bootstrap node
        if givenbootstraplist:
            self.bootstraplist = []
            self.discoverbootstrap(givenbootstraplist)
            self.connecttobootstrap()
        if self.type == NODE_REPLICA or self.type == NODE_NAMESERVER:
            self.stateuptodate = False
Beispiel #2
0
class Node():
    """Node encloses the basic Node behaviour and state that
    are extended by Leaders, Acceptors or Replicas.
    """
    def __init__(self,
                 nodetype,
                 addr=args.addr,
                 port=args.port,
                 givenbootstraplist=args.bootstrap,
                 debugoption=args.debug,
                 objectname=args.objectname,
                 instantiateobj=False,
                 configpath=args.configpath,
                 logger=args.logger,
                 writetodisk=args.writetodisk):
        self.addr = addr if addr else findOwnIP()
        self.port = port
        self.type = nodetype
        self.debug = debugoption
        self.durable = writetodisk
        if instantiateobj:
            if objectname == '':
                parser.print_help()
                self._graceexit(1)
            self.objectname = objectname
        # initialize receive queue
        self.receivedmessages_semaphore = Semaphore(0)
        self.receivedmessages = []
        # lock to synchronize message handling
        self.lock = Lock()
        # create server socket and bind to a port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.socket.setblocking(0)
        if self.port:
            try:
                self.socket.bind((self.addr,self.port))
            except socket.error as e:
                print "Cannot bind to port %d" % self.port
                print "Socket Error: ", e
                self._graceexit(1)
        else:
            for i in range(50):
                self.port = random.randint(14000,15000)
                try:
                    self.socket.bind((self.addr,self.port))
                    break
                except socket.error as e:
                    print "Socket Error: ", e
                    pass
        self.socket.listen(10)
        self.connectionpool = ConnectionPool()
        try:
            self.connectionpool.epoll = select.epoll()
        except AttributeError as e:
            # the os doesn't support epoll
            self.connectionpool.epoll = None
        self.alive = True
        self.me = Peer(self.addr,self.port,self.type)
        # set id
        self.id = '%s:%d' % (self.addr, self.port)

        # set path for additional configuration data
        self.configpath = configpath
        # set the logger
        try:
            LOGGERNODE = load_configdict(self.configpath)['LOGGERNODE']
        except KeyError as e:
            if logger:
                LOGGERNODE=logger
            else:
                LOGGERNODE = None
        self.logger = Logger("%s-%s" % (node_names[self.type],self.id), lognode=LOGGERNODE)
        print "%s-%s connected." % (node_names[self.type],self.id)
        # Initialize groups
        # Keeps {peer:outofreachcount}
        self.replicas = {}
        self.acceptors = {}
        self.nameservers = {}
        self.groups = {NODE_REPLICA: self.replicas,
                       NODE_ACCEPTOR: self.acceptors,
                       NODE_NAMESERVER: self.nameservers}
        self.groups[self.me.type][self.me] = 0

        # Keeps the liveness of the nodes
        self.nodeliveness = {}
        # connect to the bootstrap node
        if givenbootstraplist:
            self.bootstraplist = []
            self.discoverbootstrap(givenbootstraplist)
            self.connecttobootstrap()
        if self.type == NODE_REPLICA or self.type == NODE_NAMESERVER:
            self.stateuptodate = False

    def _getipportpairs(self, bootaddr, bootport):
        for node in socket.getaddrinfo(bootaddr, bootport, socket.AF_INET, socket.SOCK_STREAM):
            yield Peer(node[4][0],bootport,NODE_REPLICA)

    def discoverbootstrap(self, givenbootstraplist):
        bootstrapstrlist = givenbootstraplist.split(",")
        for bootstrap in bootstrapstrlist:
            #ipaddr:port pair given as bootstrap
            if bootstrap.find(":") >= 0:
                bootaddr,bootport = bootstrap.split(":")
                for peer in self._getipportpairs(bootaddr, int(bootport)):
                    self.bootstraplist.append(peer)
            #dnsname given as bootstrap
            else:
                answers = []
                try:
                    answers = dns.resolver.query('_concoord._tcp.'+bootstrap, 'SRV')
                except (dns.resolver.NXDOMAIN, dns.exception.Timeout):
                    if self.debug: self.logger.write("DNS Error", "Cannot resolve %s" % str(bootstrap))
                for rdata in answers:
                    for peer in self._getipportpairs(str(rdata.target), rdata.port):
                        self.bootstraplist.append(peer)

    def connecttobootstrap(self):
        tries = 0
        keeptrying = True
        while tries < BOOTSTRAPCONNECTTIMEOUT and keeptrying:
            for bootpeer in self.bootstraplist:
                try:
                    if self.debug: self.logger.write("State",
                                                     "trying to connect to bootstrap: %s" % str(bootpeer))
                    helomessage = create_message(MSG_HELO, self.me)
                    successid = self.send(helomessage, peer=bootpeer)
                    if successid < 0:
                        tries += 1
                        continue
                    keeptrying = False
                    break
                except socket.error as e:
                    if self.debug: self.logger.write("Socket Error",
                                                     "cannot connect to bootstrap: %s" % str(e))
                    tries += 1
                    continue
            time.sleep(1)

    def startservice(self):
        # Start a thread that waits for inputs
        receiver_thread = Thread(target=self.server_loop, name='ReceiverThread')
        receiver_thread.start()
        # Start a thread with the server which will start a thread for each request
        main_thread = Thread(target=self.handle_messages, name='MainThread')
        main_thread.start()
        # Start a thread that pings all neighbors
        ping_thread = Timer(LIVENESSTIMEOUT, self.ping_neighbor)
        ping_thread.name = 'PingThread'
        ping_thread.start()
        # Start a thread that goes through the nascentset and cleans expired ones
        nascent_thread = Timer(NASCENTTIMEOUT, self.clean_nascent)
        nascent_thread.name = 'NascentThread'
        nascent_thread.start()
        # Start a thread that waits for inputs
        if self.debug:
            input_thread = Thread(target=self.get_user_input_from_shell, name='InputThread')
            input_thread.start()
        return self

    def __str__(self):
        return "%s NODE %s:%d" % (node_names[self.type], self.addr, self.port)

    def statestr(self):
        returnstr = ""
        for type,group in self.groups.iteritems():
            for peer in group.iterkeys():
                returnstr += node_names[type] + " %s:%d\n" % (peer.addr,peer.port)
        if hasattr(self, 'pendingcommands') and len(self.pendingcommands) > 0:
            pending =  "".join("%d: %s" % (cno, proposal) for cno,proposal in self.pendingcommands.iteritems())
            returnstr = "%s\nPending:\n%s" % (returnstr, pending)
        return returnstr

    def ping_neighbor(self):
        """used to ping neighbors periodically"""
        # Only ping neighbors that didn't send a message in less than
        # LIVENESSTIMEOUT
        while True:
            # Check nodeliveness
            for gtype,group in self.groups.iteritems():
                for peer in group:
                    if peer == self.me:
                        continue
                    if peer in self.nodeliveness:
                        nosound = time.time() - self.nodeliveness[peer]
                    else:
                        # This node never sent a message, we should ping it
                        if self.debug: self.logger.write("State", "Sending PING to %s" % str(peer))
                        pingmessage = create_message(MSG_PING, self.me)
                        self.send(pingmessage, peer=peer)
                        continue

                    if (4*LIVENESSTIMEOUT) > nosound and nosound > LIVENESSTIMEOUT:
                        # Send PING to node
                        if self.debug: self.logger.write("State", "Sending PING to %s" % str(peer))
                        pingmessage = create_message(MSG_PING, self.me)
                        self.send(pingmessage, peer=peer)
                    elif nosound > (4*LIVENESSTIMEOUT):
                        # Neighbor not responding, mark the neighbor
                        if self.debug: self.logger.write("State",
                                                         "Neighbor not responding")
                        self.groups[peer.type][peer] += 1
            time.sleep(LIVENESSTIMEOUT)

    def clean_nascent(self):
        lastnascentset = set([])
        while True:
            for sock in lastnascentset.intersection(self.connectionpool.nascentsockets):
                # expired -- if it's not already in the set, it should be deleted
                self.connectionpool.activesockets.remove(sock)
                self.connectionpool.nascentsockets.remove(sock)
                lastnascentset = self.connectionpool.nascentsockets
            time.sleep(NASCENTTIMEOUT)

    def server_loop(self):
        """Serverloop that listens to multiple connections and accepts new ones.

        Server State
        - inputready: sockets that are ready for reading
        - exceptready: sockets that are ready according to an *exceptional condition*
        """
        self.socket.listen(10)

        if self.connectionpool.epoll:
            self.connectionpool.epoll.register(self.socket.fileno(), select.EPOLLIN)
            self.use_epoll()
        else:
            # the OS doesn't support epoll
            self.connectionpool.activesockets.add(self.socket)
            self.use_select()

        self.socket.close()
        return

    def use_epoll(self):
        while self.alive:
            try:
                events = self.connectionpool.epoll.poll(1)
                for fileno, event in events:
                    if fileno == self.socket.fileno():
                        clientsock, clientaddr = self.socket.accept()
                        clientsock.setblocking(0)
                        self.connectionpool.epoll.register(clientsock.fileno(), select.EPOLLIN)
                        self.connectionpool.epollsockets[clientsock.fileno()] = clientsock
                    elif event & select.EPOLLIN:
                        success = self.handle_connection(self.connectionpool.epollsockets[fileno])
                        if not success:
                            self.connectionpool.epoll.unregister(fileno)
                            self.connectionpool.del_connection_by_socket(self.connectionpool.epollsockets[fileno])
                            self.connectionpool.epollsockets[fileno].close()
                            del self.connectionpool.epollsockets[fileno]
                    elif event & select.EPOLLHUP:
                        self.connectionpool.epoll.unregister(fileno)
                        self.connectionpool.epollsockets[fileno].close()
                        del self.connectionpool.epollsockets[fileno]
            except KeyboardInterrupt, EOFError:
                os._exit(0)
        self.connectionpool.epoll.unregister(self.socket.fileno())
        self.connectionpool.epoll.close()
Beispiel #3
0
    def __init__(self,
                 addr=args.addr,
                 port=args.port,
                 givenbootstraplist=args.bootstrap,
                 debugoption=args.debug,
                 objectname=args.objectname,
                 logger=args.logger,
                 writetodisk=args.writetodisk):
        self.addr = addr if addr else findOwnIP()
        self.port = port
        self.debug = debugoption
        self.durable = writetodisk
        self.isnameserver = args.domain != ''
        self.domain = args.domain
        self.useroute53 = args.route53
        if objectname == '':
            parser.print_help()
            self._graceexit(1)
        self.objectname = objectname
        # initialize receive queue
        self.receivedmessages_semaphore = Semaphore(0)
        self.receivedmessages = []
        # lock to synchronize message handling
        self.lock = Lock()

        # create server socket and bind to a port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.socket.setblocking(0)
        if self.port:
            try:
                self.socket.bind((self.addr, self.port))
            except socket.error as e:
                print "Cannot bind to port %d" % self.port
                print "Socket Error: ", e
                self._graceexit(1)
        else:
            for i in range(50):
                self.port = random.randint(14000, 15000)
                try:
                    self.socket.bind((self.addr, self.port))
                    break
                except socket.error as e:
                    print "Socket Error: ", e
        self.socket.listen(10)
        self.connectionpool = ConnectionPool()

        try:
            self.connectionpool.epoll = select.epoll()
        except AttributeError as e:
            # the os doesn't support epoll
            self.connectionpool.epoll = None

        # set the logger
        if logger:
            LOGGERNODE = logger
        else:
            LOGGERNODE = None

        # Initialize replicas
        # Keeps {peer:outofreachcount}
        self.replicas = {}
        # Nameserver state
        if self.isnameserver:
            self.type = NODE_NAMESERVER
            try:
                self.nameserver = Nameserver(self.addr, self.domain,
                                             self.useroute53, self.replicas,
                                             self.debug)
            except Exception as e:
                print "Error:", e
                print "Could not start Replica as a Nameserver, exiting."
                self._graceexit(1)
        else:
            self.type = NODE_REPLICA

        self.alive = True
        self.me = Peer(self.addr, self.port, self.type)
        # set id
        self.id = '%s:%d' % (self.addr, self.port)
        # add self to connectionpool
        self.connectionpool.add_connection_to_self(
            self.me,
            SelfConnection(self.receivedmessages,
                           self.receivedmessages_semaphore))
        self.logger = Logger("%s-%s" % (node_names[self.type], self.id),
                             lognode=LOGGERNODE)
        if self.isnameserver:
            self.nameserver.add_logger(self.logger)
        print "%s-%s connected." % (node_names[self.type], self.id)

        # Keeps the liveness of the nodes
        self.nodeliveness = {}
        self.bootstrapset = set()
        # connect to the bootstrap node
        if givenbootstraplist:
            self.discoverbootstrap(givenbootstraplist)
            self.connecttobootstrap()

        self.stateuptodate = False
Beispiel #4
0
class Node():
    """Node encloses the basic Node behaviour and state that
    are extended by Replicas and Nameservers.
    """
    def __init__(self,
                 addr=args.addr,
                 port=args.port,
                 givenbootstraplist=args.bootstrap,
                 debugoption=args.debug,
                 objectname=args.objectname,
                 logger=args.logger,
                 writetodisk=args.writetodisk):
        self.addr = addr if addr else findOwnIP()
        self.port = port
        self.debug = debugoption
        self.durable = writetodisk
        self.isnameserver = args.domain != ''
        self.domain = args.domain
        self.useroute53 = args.route53
        if objectname == '':
            parser.print_help()
            self._graceexit(1)
        self.objectname = objectname
        # initialize receive queue
        self.receivedmessages_semaphore = Semaphore(0)
        self.receivedmessages = []
        # lock to synchronize message handling
        self.lock = Lock()

        # create server socket and bind to a port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.socket.setblocking(0)
        if self.port:
            try:
                self.socket.bind((self.addr, self.port))
            except socket.error as e:
                print "Cannot bind to port %d" % self.port
                print "Socket Error: ", e
                self._graceexit(1)
        else:
            for i in range(50):
                self.port = random.randint(14000, 15000)
                try:
                    self.socket.bind((self.addr, self.port))
                    break
                except socket.error as e:
                    print "Socket Error: ", e
        self.socket.listen(10)
        self.connectionpool = ConnectionPool()

        try:
            self.connectionpool.epoll = select.epoll()
        except AttributeError as e:
            # the os doesn't support epoll
            self.connectionpool.epoll = None

        # set the logger
        if logger:
            LOGGERNODE = logger
        else:
            LOGGERNODE = None

        # Initialize replicas
        # Keeps {peer:outofreachcount}
        self.replicas = {}
        # Nameserver state
        if self.isnameserver:
            self.type = NODE_NAMESERVER
            try:
                self.nameserver = Nameserver(self.addr, self.domain,
                                             self.useroute53, self.replicas,
                                             self.debug)
            except Exception as e:
                print "Error:", e
                print "Could not start Replica as a Nameserver, exiting."
                self._graceexit(1)
        else:
            self.type = NODE_REPLICA

        self.alive = True
        self.me = Peer(self.addr, self.port, self.type)
        # set id
        self.id = '%s:%d' % (self.addr, self.port)
        # add self to connectionpool
        self.connectionpool.add_connection_to_self(
            self.me,
            SelfConnection(self.receivedmessages,
                           self.receivedmessages_semaphore))
        self.logger = Logger("%s-%s" % (node_names[self.type], self.id),
                             lognode=LOGGERNODE)
        if self.isnameserver:
            self.nameserver.add_logger(self.logger)
        print "%s-%s connected." % (node_names[self.type], self.id)

        # Keeps the liveness of the nodes
        self.nodeliveness = {}
        self.bootstrapset = set()
        # connect to the bootstrap node
        if givenbootstraplist:
            self.discoverbootstrap(givenbootstraplist)
            self.connecttobootstrap()

        self.stateuptodate = False

    def _getipportpairs(self, bootaddr, bootport):
        for node in socket.getaddrinfo(bootaddr, bootport, socket.AF_INET,
                                       socket.SOCK_STREAM):
            yield Peer(node[4][0], bootport, NODE_REPLICA)

    def discoverbootstrap(self, givenbootstraplist):
        bootstrapstrlist = givenbootstraplist.split(",")
        for bootstrap in bootstrapstrlist:
            #ipaddr:port pair given as bootstrap
            if bootstrap.find(":") >= 0:
                bootaddr, bootport = bootstrap.split(":")
                for peer in self._getipportpairs(bootaddr, int(bootport)):
                    self.bootstrapset.add(peer)
            #dnsname given as bootstrap
            else:
                answers = []
                try:
                    answers = dns.resolver.query('_concoord._tcp.' + bootstrap,
                                                 'SRV')
                except (dns.resolver.NXDOMAIN, dns.exception.Timeout):
                    if self.debug:
                        self.logger.write("DNS Error",
                                          "Cannot resolve %s" % str(bootstrap))
                for rdata in answers:
                    for peer in self._getipportpairs(str(rdata.target),
                                                     rdata.port):
                        self.bootstrapset.append(peer)

    def connecttobootstrap(self):
        tries = 0
        keeptrying = True
        while tries < BOOTSTRAPCONNECTTIMEOUT and keeptrying:
            for bootpeer in self.bootstrapset:
                try:
                    if self.debug:
                        self.logger.write(
                            "State", "trying to connect to bootstrap: %s" %
                            str(bootpeer))
                    helomessage = create_message(MSG_HELO, self.me)
                    successid = self.send(helomessage, peer=bootpeer)
                    if successid < 0:
                        tries += 1
                        continue
                    keeptrying = False
                    break
                except socket.error as e:
                    if self.debug:
                        self.logger.write(
                            "Socket Error",
                            "cannot connect to bootstrap: %s" % str(e))
                    tries += 1
                    continue
            time.sleep(1)

    def startservice(self):
        # Start a thread that waits for inputs
        receiver_thread = Thread(target=self.server_loop,
                                 name='ReceiverThread')
        receiver_thread.start()
        # Start a thread with the server which will start a thread for each request
        main_thread = Thread(target=self.handle_messages, name='MainThread')
        main_thread.start()
        # Start a thread that pings all neighbors
        ping_thread = Timer(LIVENESSTIMEOUT, self.ping_neighbor)
        ping_thread.name = 'PingThread'
        ping_thread.start()
        # Start a thread that goes through the nascentset and cleans expired ones
        nascent_thread = Timer(NASCENTTIMEOUT, self.clean_nascent)
        nascent_thread.name = 'NascentThread'
        nascent_thread.start()
        # Start a thread that waits for inputs
        if self.debug:
            input_thread = Thread(target=self.get_user_input_from_shell,
                                  name='InputThread')
            input_thread.start()
        return self

    def __str__(self):
        return "%s NODE %s:%d" % (node_names[self.type], self.addr, self.port)

    def statestr(self):
        returnstr = ""
        for peer in self.replicas:
            returnstr += node_names[peer.type] + " %s:%d\n" % (peer.addr,
                                                               peer.port)
        if hasattr(self, 'pendingcommands') and len(self.pendingcommands) > 0:
            pending =  "".join("%d: %s" % (cno, proposal) for cno,proposal \
                                   in self.pendingcommands.iteritems())
            returnstr = "%s\nPending:\n%s" % (returnstr, pending)
        return returnstr

    def ping_neighbor(self):
        """used to ping neighbors periodically"""
        # Only ping neighbors that didn't send a message recently
        while True:
            # Check nodeliveness
            for peer in self.replicas:
                if peer == self.me:
                    continue
                if peer in self.nodeliveness:
                    nosound = time.time() - self.nodeliveness[peer]
                else:
                    nosound = LIVENESSTIMEOUT + 1

                if nosound <= LIVENESSTIMEOUT:
                    # Peer is alive
                    self.replicas[peer] = 0
                    continue
                if nosound > LIVENESSTIMEOUT:
                    # Send PING to node
                    if self.debug:
                        self.logger.write("State",
                                          "Sending PING to %s" % str(peer))
                    pingmessage = create_message(MSG_PING, self.me)
                    successid = self.send(pingmessage, peer=peer)
                if successid < 0 or nosound > (2 * LIVENESSTIMEOUT):
                    # Neighbor not responding, mark the neighbor
                    if self.debug:
                        self.logger.write("State", "Neighbor not responding")
                    self.replicas[peer] += 1
            time.sleep(LIVENESSTIMEOUT)

    def clean_nascent(self):
        lastnascentset = set([])
        while True:
            for sock in lastnascentset.intersection(
                    self.connectionpool.nascentsockets):
                # expired -- if it's not already in the set, it should be deleted
                self.connectionpool.activesockets.remove(sock)
                self.connectionpool.nascentsockets.remove(sock)
                lastnascentset = self.connectionpool.nascentsockets
            time.sleep(NASCENTTIMEOUT)

    def server_loop(self):
        """Serverloop that listens to multiple connections and accepts new ones.

        Server State
        - inputready: sockets that are ready for reading
        - exceptready: sockets that are ready according to an *exceptional condition*
        """
        self.socket.listen(10)

        if self.connectionpool.epoll:
            self.connectionpool.epoll.register(self.socket.fileno(),
                                               select.EPOLLIN)
            self.use_epoll()
        else:
            # the OS doesn't support epoll
            self.connectionpool.activesockets.add(self.socket)
            self.use_select()

        self.socket.close()
        return

    def use_epoll(self):
        while self.alive:
            try:
                events = self.connectionpool.epoll.poll(1)
                for fileno, event in events:
                    if fileno == self.socket.fileno():
                        clientsock, clientaddr = self.socket.accept()
                        clientsock.setblocking(0)
                        self.connectionpool.epoll.register(
                            clientsock.fileno(), select.EPOLLIN)
                        self.connectionpool.epollsockets[
                            clientsock.fileno()] = clientsock
                    elif event & select.EPOLLIN:
                        success = self.handle_connection(
                            self.connectionpool.epollsockets[fileno])
                        if not success:
                            self.connectionpool.epoll.unregister(fileno)
                            self.connectionpool.del_connection_by_socket(
                                self.connectionpool.epollsockets[fileno])
                            self.connectionpool.epollsockets[fileno].close()
                            del self.connectionpool.epollsockets[fileno]
                    elif event & select.EPOLLHUP:
                        self.connectionpool.epoll.unregister(fileno)
                        self.connectionpool.epollsockets[fileno].close()
                        del self.connectionpool.epollsockets[fileno]
            except KeyboardInterrupt, EOFError:
                os._exit(0)
        self.connectionpool.epoll.unregister(self.socket.fileno())
        self.connectionpool.epoll.close()
Beispiel #5
0
    def __init__(self,
                 addr=args.addr,
                 port=args.port,
                 givenbootstraplist=args.bootstrap,
                 debugoption=args.debug,
                 objectname=args.objectname,
                 logger=args.logger,
                 writetodisk=args.writetodisk):
        self.addr = addr if addr else findOwnIP()
        self.port = port
        self.debug = debugoption
        self.durable = writetodisk
        self.isnameserver = args.domain != ''
        self.domain = args.domain
        self.useroute53 = args.route53
        if objectname == '':
            parser.print_help()
            self._graceexit(1)
        self.objectname = objectname
        # initialize receive queue
        self.receivedmessages_semaphore = Semaphore(0)
        self.receivedmessages = []
        # lock to synchronize message handling
        self.lock = Lock()

        # create server socket and bind to a port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.socket.setblocking(0)
        if self.port:
            try:
                self.socket.bind((self.addr,self.port))
            except socket.error as e:
                print "Cannot bind to port %d" % self.port
                print "Socket Error: ", e
                self._graceexit(1)
        else:
            for i in range(50):
                self.port = random.randint(14000,15000)
                try:
                    self.socket.bind((self.addr,self.port))
                    break
                except socket.error as e:
                    print "Socket Error: ", e
        self.socket.listen(10)
        self.connectionpool = ConnectionPool()

        try:
            self.connectionpool.epoll = select.epoll()
        except AttributeError as e:
            # the os doesn't support epoll
            self.connectionpool.epoll = None

        # set the logger
        if logger:
            LOGGERNODE = logger
        else:
            LOGGERNODE = None

        # Initialize replicas
        # Keeps {peer:outofreachcount}
        self.replicas = {}
        # Nameserver state
        if self.isnameserver:
            self.type = NODE_NAMESERVER
            try:
                self.nameserver = Nameserver(self.addr, self.domain, self.useroute53,
                                             self.replicas, self.debug)
            except Exception as e:
                print "Error:", e
                print "Could not start Replica as a Nameserver, exiting."
                self._graceexit(1)
        else:
            self.type = NODE_REPLICA

        self.alive = True
        self.me = Peer(self.addr,self.port,self.type)
        # set id
        self.id = '%s:%d' % (self.addr, self.port)
        # add self to connectionpool
        self.connectionpool.add_connection_to_self(self.me,
                                                   SelfConnection(self.receivedmessages,
                                                                  self.receivedmessages_semaphore))
        self.logger = Logger("%s-%s" % (node_names[self.type],self.id), lognode=LOGGERNODE)
        if self.isnameserver:
            self.nameserver.add_logger(self.logger)
        print "%s-%s connected." % (node_names[self.type],self.id)

        # Keeps the liveness of the nodes
        self.nodeliveness = {}
        self.bootstrapset = set()
        # connect to the bootstrap node
        if givenbootstraplist:
            self.discoverbootstrap(givenbootstraplist)
            self.connecttobootstrap()

        self.stateuptodate = False
Beispiel #6
0
    def __init__(self,
                 nodetype,
                 addr=args.addr,
                 port=args.port,
                 givenbootstraplist=args.bootstrap,
                 debugoption=args.debug,
                 objectname=args.objectname,
                 instantiateobj=False,
                 configpath=args.configpath,
                 logger=args.logger,
                 writetodisk=args.writetodisk):
        self.addr = addr if addr else findOwnIP()
        self.port = port
        self.type = nodetype
        self.debug = debugoption
        self.durable = writetodisk
        if instantiateobj:
            if objectname == '':
                parser.print_help()
                self._graceexit(1)
            self.objectname = objectname
        # initialize receive queue
        self.receivedmessages_semaphore = Semaphore(0)
        self.receivedmessages = []
        # lock to synchronize message handling
        self.lock = Lock()
        # create server socket and bind to a port
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
        self.socket.setblocking(0)
        if self.port:
            try:
                self.socket.bind((self.addr, self.port))
            except socket.error as e:
                print "Cannot bind to port %d" % self.port
                print "Socket Error: ", e
                self._graceexit(1)
        else:
            for i in range(50):
                self.port = random.randint(14000, 15000)
                try:
                    self.socket.bind((self.addr, self.port))
                    break
                except socket.error as e:
                    print "Socket Error: ", e
                    pass
        self.socket.listen(10)
        self.connectionpool = ConnectionPool()
        try:
            self.connectionpool.epoll = select.epoll()
        except AttributeError as e:
            # the os doesn't support epoll
            self.connectionpool.epoll = None
        self.alive = True
        self.me = Peer(self.addr, self.port, self.type)
        # set id
        self.id = '%s:%d' % (self.addr, self.port)

        # set path for additional configuration data
        self.configpath = configpath
        # set the logger
        try:
            LOGGERNODE = load_configdict(self.configpath)['LOGGERNODE']
        except KeyError as e:
            if logger:
                LOGGERNODE = logger
            else:
                LOGGERNODE = None
        self.logger = Logger("%s-%s" % (node_names[self.type], self.id),
                             lognode=LOGGERNODE)
        print "%s-%s connected." % (node_names[self.type], self.id)
        # Initialize groups
        # Keeps {peer:outofreachcount}
        self.replicas = {}
        self.acceptors = {}
        self.nameservers = {}
        self.groups = {
            NODE_REPLICA: self.replicas,
            NODE_ACCEPTOR: self.acceptors,
            NODE_NAMESERVER: self.nameservers
        }
        self.groups[self.me.type][self.me] = 0

        # Keeps the liveness of the nodes
        self.nodeliveness = {}
        # connect to the bootstrap node
        if givenbootstraplist:
            self.bootstraplist = []
            self.discoverbootstrap(givenbootstraplist)
            self.connecttobootstrap()
        if self.type == NODE_REPLICA or self.type == NODE_NAMESERVER:
            self.stateuptodate = False