def serve(self, interface='0.0.0.0', port=3000):
        
        self.log.info('ZenQueue Native Server v%s', zenqueue.__version__)
        if interface == '0.0.0.0':
            self.log.info('Serving on %s:%d (all interfaces)', interface, port)
        else:
            self.log.info('Serving on %s:%d', interface, port)
        
        self.socket = api.tcp_listener((interface, port))
        
        # A lot of the code below was copied or adapted from eventlet's
        # implementation of an asynchronous WSGI server.
        try:
            while True:
                try:
                    try:
                        client_socket, client_addr = self.socket.accept()
                    except socket.error, exc:
                        # EPIPE (Broken Pipe) and EBADF (Bad File Descriptor)
                        # errors are common for clients that suddenly quit. We
                        # shouldn't worry so much about them.
                        if exc[0] not in [errno.EPIPE, errno.EBADF]:
                            raise
                    # Throughout the logging output, we use the client's ID in
                    # hexadecimal to identify a particular client in the logs.
                    self.log.info('Client %x connected: %r',
                        id(client_socket), client_addr)
                    # Handle this client on the pool, sleeping for 0 time to
                    # allow the handler (or other coroutines) to run.
                    self.client_pool.execute_async(self.handle, client_socket)
                    api.sleep(0)
                
                except __HOLE__:
                    # It's a fatal error because it kills the program.
                    self.log.fatal('Received keyboard interrupt.')
                    # This removes the socket from the current hub's list of
                    # sockets to check for clients (i.e. the select() call).
                    # select() is a key component of asynchronous networking.
                    api.get_hub().remove_descriptor(self.socket.fileno())
                    break
        finally:
            try:
                self.log.info('Shutting down server.')
                self.socket.close()
            except socket.error, exc:
                # See above for why we shouldn't worry about Broken Pipe or Bad
                # File Descriptor errors.
                if exc[0] not in [errno.EPIPE, errno.EBADF]:
                    raise
            finally:
                self.socket = None
dataset/ETHPy150Open zacharyvoase/zenqueue/zenqueue/server/native.py/NativeQueueServer.serve