Repository: locustio/locust
File: locust/runners.py (Python)

Code before:
                "spawn_rate": worker_spawn_rate,
                "num_users": worker_num_users,
                "host": self.environment.host,
                "stop_timeout": self.environment.stop_timeout,
            }

            if remaining > 0:
                data["num_users"] += 1
                remaining -= 1

            self.server.send_to_client(Message("spawn", data, client.id))

        self.state = STATE_SPAWNING

    def stop(self):
        if self.state not in [STATE_INIT, STATE_STOPPED, STATE_STOPPING]:
            self.state = STATE_STOPPING

            if self.environment.shape_class:
                self.shape_last_state = None

            for client in self.clients.all:
                self.server.send_to_client(Message("stop", None, client.id))
            self.environment.events.test_stop.fire(environment=self.environment)

    def quit(self):
        if self.state not in [STATE_INIT, STATE_STOPPED, STATE_STOPPING]:
            # fire test_stop event if state isn't already stopped
            self.environment.events.test_stop.fire(environment=self.environment)

        for client in self.clients.all:
            self.server.send_to_client(Message("quit", None, client.id))
        gevent.sleep(0.5)  # wait for final stats report from all workers
        self.greenlet.kill(block=True)

    def check_stopped(self):
        if not self.state == STATE_INIT and all(
            map(lambda x: x.state != STATE_RUNNING and x.state != STATE_SPAWNING, self.clients.all)
        ):
            self.state = STATE_STOPPED

    def heartbeat_worker(self):
        while True:
            gevent.sleep(HEARTBEAT_INTERVAL)
            if self.connection_broken:
                self.reset_connection()
                continue

            for client in self.clients.all:
                if client.heartbeat < 0 and client.state != STATE_MISSING:
                    logger.info("Worker %s failed to send heartbeat, setting state to missing." % str(client.id))

Review comment (suggestion):
oh, but I think this line is no longer needed. you can remove it as part of the actual fix later on :)

Code after:

        if self.state != STATE_RUNNING and self.state != STATE_SPAWNING:
            self.stats.clear_all()
            self.exceptions = {}
            self.environment.events.test_start.fire(environment=self.environment)

        for client in self.clients.ready + self.clients.running + self.clients.spawning:
            data = {
                "spawn_rate": worker_spawn_rate,
                "num_users": worker_num_users,
                "host": self.environment.host,
                "stop_timeout": self.environment.stop_timeout,
            }

            if remaining > 0:
                data["num_users"] += 1
                remaining -= 1

            logger.debug("Sending spawn message to client %s" % (client.id))
            self.server.send_to_client(Message("spawn", data, client.id))

        self.update_state(STATE_SPAWNING)

    def stop(self):
        if self.state not in [STATE_INIT, STATE_STOPPED, STATE_STOPPING]:
            logger.debug("Stopping...")
            self.update_state(STATE_STOPPING)

            if self.environment.shape_class:
                self.shape_last_state = None

            for client in self.clients.all:
                logger.debug("Sending stop message to client %s" % (client.id))
                self.server.send_to_client(Message("stop", None, client.id))

            self.environment.events.test_stop.fire(environment=self.environment)

    def quit(self):
        if self.state not in [STATE_INIT, STATE_STOPPED, STATE_STOPPING]:
            logger.debug("Quitting...")
            # fire test_stop event if state isn't already stopped
            self.environment.events.test_stop.fire(environment=self.environment)

        for client in self.clients.all:
            logger.debug("Sending quit message to client %s" % (client.id))
            self.server.send_to_client(Message("quit", None, client.id))
        gevent.sleep(0.5)  # wait for final stats report from all workers
        self.greenlet.kill(block=True)

    def check_stopped(self):
        if not self.state == STATE_INIT and all(