예제 #1
0
    def shutdown(self, e=None):
        LOGGER.warning('Shut down!')

        if e:
            LOGGER.critical(e)

        try:
            for client in self.clients:
                client.shutdown()
        except Exception as e:
            LOGGER.error('Something went wrong while shutting down clients')
            LOGGER.error(e)

        try:
            if self.tcpdump_proc:
                self.tcpdump_proc.send_signal(signal.SIGINT)
        except Exception as e:
            LOGGER.error('Something went wrong while shutting down TCPDUMP')
            LOGGER.error(e)

        try:
            if self.backend_mgr:
                self.backend_mgr.shutdown()
        except Exception as e:
            LOGGER.error(
                'Something went wrong while shutting down Docker containers')
            LOGGER.error(e)
예제 #2
0
    def execute(self):
        server_socket = None
        error = None

        try:
            # first start docker instances
            self.backend_mgr.spawn_backends()

            with socket(AF_INET, SOCK_STREAM) as server_socket:
                server_socket.bind((self.host, self.port))
                server_socket.listen(self.config.clients)
                server_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
                LOGGER.info('Listening on %s:%d', self.host, self.port)

                # accept N clients for the experiment
                LOGGER.info('Waiting for %d clients to connect...',
                            self.config.clients)

                signal.signal(signal.SIGINT, signal_handler)
                signal.signal(signal.SIGTERM, signal_handler)

                # wait for all clients to connect
                for i in range(self.config.clients):
                    conn, addr = server_socket.accept()
                    set_keepalive_linux(conn, max_fails=100)  # 5 minutes

                    client = AsyncClient(conn, addr,
                                         self._gen_config_for_client(i))

                    self.clients.append(client)

                    LOGGER.info('{} out of {} clients connected: {}:{}'.format(
                        i + 1, self.config.clients, *addr))
                    # send config
                    client.send_config()

                # wait for clients to finish sending configs
                for c in self.clients:
                    c.wait_for_tasks()

                # send traces, two clients at the time
                LOGGER.info('Pushing step files to clients...')

                # grouper is a generator, so wrap it in a list
                chunks = list(grouper(self.clients, 2, fillvalue=NullClient()))

                # use list comprehensions to avoid laziness (map())
                step_data = [
                    open(p, 'rb').read() for p in self.config.trace_steps
                ]
                step_chksums = [hashlib.md5(d).hexdigest() for d in step_data]

                steps = zip(itertools.count(start=1), step_chksums, step_data)

                for chunk, step in itertools.product(chunks, steps):
                    for c in chunk:
                        c.send_step(*step)
                    for c in chunk:
                        c.wait_for_tasks()

                # execute runs!
                for r in range(self.config.runs):
                    self.__execute_run(r)

        except ShutdownException:
            pass

        except Exception as e:
            error = e

        finally:
            try:
                if server_socket:
                    # server_socket.shutdown(SHUT_RDWR)
                    server_socket.close()
            except Exception as e:
                LOGGER.critical('Error closing server socket.')
                LOGGER.critical(e)

            self.shutdown(e=error)