def _start(self):
        # Need credentials in case we're using a PublicKey server.
        credentials = get_credentials()

        # Determine maximum number of servers available.
        resources = {
            'required_distributions': self._egg_required_distributions,
            'orphan_modules': self._egg_orphan_modules,
            'python_version': sys.version[:3]
        }
        if self.extra_resources:
            resources.update(self.extra_resources)
        max_servers = RAM.max_servers(resources)
        self._logger.debug('max_servers %d', max_servers)
        if max_servers <= 0:
            msg = 'No servers supporting required resources %s' % resources
            self.raise_exception(msg, RuntimeError)

        # Kick off initial wave of cases.
        self._server_lock = threading.Lock()
        self._reply_q = Queue.Queue()
        self._generation += 1
        n_servers = 0
        while n_servers < max_servers:
            if not self._more_to_go():
                break

            # Get next case. Limits servers started if max_servers > cases.
            try:
                case = self._iter.next()
            except StopIteration:
                if not self._rerun:
                    self._iter = None
                    break

            self._todo.append(case)

            # Start server worker thread.
            n_servers += 1
            name = '%s_%d_%d' % (self.name, self._generation, n_servers)
            self._logger.debug('starting worker for %r', name)
            server = self._servers[name] = _ServerData(name)
            server.in_use = True
            server_thread = threading.Thread(target=self._service_loop,
                                             args=(name, resources,
                                                   credentials, self._reply_q))
            server_thread.daemon = True
            try:
                server_thread.start()
            except thread.error:
                self._logger.warning('worker thread startup failed for %r',
                                     name)
                server.in_use = False
                break

            if sys.platform != 'win32':
                # Process any pending events.
                while self._busy():
                    try:
                        name, result, exc = self._reply_q.get(True, 0.01)
                    except Queue.Empty:
                        break  # Timeout.
                    else:
                        # Difficult to force startup failure.
                        if server.server is None:  # pragma nocover
                            self._logger.debug('server startup failed for %r',
                                               name)
                            server.in_use = False
                        else:
                            server.in_use = self._server_ready(server)

        if sys.platform == 'win32':  # pragma no cover
            # Don't start server processing until all servers are started,
            # otherwise we have egg removal issues.
            for i in self._servers:
                name, result, exc = self._reply_q.get()
                server = self._servers[name]
                if server.server is None:
                    self._logger.debug('server startup failed for %r', name)
                    server.in_use = False

            # Kick-off started servers.
            for server in self._servers.values():
                if server.in_use:
                    server.in_use = self._server_ready(server)

        # Continue until no servers are busy.
        while self._busy():
            if self._more_to_go():
                timeout = None
            else:
                # Don't wait indefinitely for a server we don't need.
                # This has happened with a server that got 'lost'
                # in RAM.allocate()
                timeout = 60
            try:
                name, result, exc = self._reply_q.get(timeout=timeout)
            # Hard to force worker to hang, which is handled here.
            except Queue.Empty:  # pragma no cover
                msgs = []
                for name, server in self._servers.items():
                    if server.in_use:
                        if server.server is None or server.info is None:
                            msgs.append('%r: no startup reply' % name)
                            server.in_use = False
                        else:
                            state = server.state
                            if state not in (_LOADING, _EXECUTING):
                                msgs.append('%r: %r %s %s'
                                            % (name, server.server,
                                               state, server.info))
                                server.in_use = False
                if msgs:
                    self._logger.error('Timeout waiting with nothing left to do:')
                    for msg in msgs:
                        self._logger.error('    %s', msg)
            else:
                server = self._servers[name]
                server.in_use = self._server_ready(server)

        # Shut-down (started) servers.
        self._logger.debug('Shut-down (started) servers')
        n_queues = 0
        for server in self._servers.values():
            if server.queue is not None:
                server.queue.put(None)
                n_queues += 1
        for i in range(n_queues):
            try:
                name, status, exc = self._reply_q.get(True, 60)
            # Hard to force worker to hang, which is handled here.
            except Queue.Empty:  # pragma no cover
                pass
            else:
                self._servers[name].queue = None
        # Hard to force worker to hang, which is handled here.
        for server in self._servers.values():  # pragma no cover
            if server.queue is not None:
                self._logger.warning('Timeout waiting for %r to shut-down.',
                                     server.name)
Start evaluating cases concurrently.
dataset/ETHPy150Open OpenMDAO/OpenMDAO-Framework/openmdao.lib/src/openmdao/lib/drivers/caseiterdriver.py/CaseIteratorDriver._start