# Buggy code
def __init__(self, *args, master_host, master_port, **kwargs):
    super().__init__(*args, **kwargs)
    self.client_id = socket.gethostname() + "_" + uuid4().hex
    self.master_host = master_host
    self.master_port = master_port
    self.client = rpc.Client(master_host, master_port, self.client_id)
    self.greenlet.spawn(self.heartbeat)
    self.greenlet.spawn(self.worker)
    self.client.send(Message("client_ready", None, self.client_id))
    self.worker_state = STATE_INIT
    self.greenlet.spawn(self.stats_reporter)

    # register listener for when all locust users have hatched, and report it to the master node
    def on_hatch_complete(user_count):
        self.client.send(
            Message("hatch_complete", {"count": user_count}, self.client_id)
        )
        self.worker_state = STATE_RUNNING

    self.environment.events.hatch_complete.add_listener(on_hatch_complete)

    # register listener that adds the current number of spawned locusts to the report that is sent to the master node
    def on_report_to_master(client_id, data):
        data["user_count"] = self.user_count

    self.environment.events.report_to_master.add_listener(on_report_to_master)

    # register listener that sends quit message to master
    def on_quitting():
        self.client.send(Message("quit", None, self.client_id))

    self.environment.events.quitting.add_listener(on_quitting)

    # register listener thats sends locust exceptions to master
    def on_locust_error(locust_instance, exception, tb):
        formatted_tb = "".join(traceback.format_tb(tb))
        self.client.send(
            Message(
                "exception",
                {"msg": str(exception), "traceback": formatted_tb},
                self.client_id,
            )
        )

    self.environment.events.locust_error.add_listener(on_locust_error)


# Traceback (ValueError)
[2020-04-06 13:01:45,700] Jonatans-Air.localdomain/ERROR/stderr: Traceback (most recent call last):
[2020-04-06 13:01:45,700] Jonatans-Air.localdomain/ERROR/stderr: File "/Users/heyman/virtualenvs/locust/bin/locust", line 11, in <module>
[2020-04-06 13:01:45,702] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,702] Jonatans-Air.localdomain/ERROR/stderr: load_entry_point('locustio', 'console_scripts', 'locust')()
[2020-04-06 13:01:45,702] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,702] Jonatans-Air.localdomain/ERROR/stderr: File "/Users/heyman/projects/locust/locust/main.py", line 297, in main
[2020-04-06 13:01:45,703] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,703] Jonatans-Air.localdomain/ERROR/stderr: shutdown(code=code)
[2020-04-06 13:01:45,703] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,704] Jonatans-Air.localdomain/ERROR/stderr: File "/Users/heyman/projects/locust/locust/main.py", line 281, in shutdown
[2020-04-06 13:01:45,705] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,705] Jonatans-Air.localdomain/ERROR/stderr: write_stat_csvs(runner.stats, options.csvfilebase, options.stats_history_enabled)
[2020-04-06 13:01:45,705] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,706] Jonatans-Air.localdomain/ERROR/stderr: File "/Users/heyman/projects/locust/locust/stats.py", line 757, in write_stat_csvs
[2020-04-06 13:01:45,706] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,706] Jonatans-Air.localdomain/ERROR/stderr: f.write(stats_history_csv(stats, stats_history_enabled) + "\n")
[2020-04-06 13:01:45,707] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,707] Jonatans-Air.localdomain/ERROR/stderr: File "/Users/heyman/projects/locust/locust/stats.py", line 871, in stats_history_csv
[2020-04-06 13:01:45,708] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,708] Jonatans-Air.localdomain/ERROR/stderr: percentile_str = ','.join([
[2020-04-06 13:01:45,708] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,708] Jonatans-Air.localdomain/ERROR/stderr: File "/Users/heyman/projects/locust/locust/stats.py", line 872, in <listcomp>
[2020-04-06 13:01:45,709] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,710] Jonatans-Air.localdomain/ERROR/stderr: str(int(s.get_current_response_time_percentile(x) or 0)) for x in PERCENTILES_TO_REPORT])
[2020-04-06 13:01:45,710] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,710] Jonatans-Air.localdomain/ERROR/stderr: File "/Users/heyman/projects/locust/locust/stats.py", line 508, in get_current_response_time_percentile
[2020-04-06 13:01:45,711] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,711] Jonatans-Air.localdomain/ERROR/stderr: raise ValueError("StatsEntry.use_response_times_cache must be set to True if we should be able to calculate the _current_ response time percentile")
[2020-04-06 13:01:45,711] Jonatans-Air.localdomain/ERROR/stderr:
[2020-04-06 13:01:45,711] Jonatans-Air.localdomain/ERROR/stderr: ValueError
[2020-04-06 13:01:45,711] Jonatans-Air.localdomain/ERROR/stderr: :
[2020-04-06 13:01:45,711] Jonatans-Air.localdomain/ERROR/stderr: StatsEntry.use_response_times_cache must be set to True if we should be able to calculate the _current_ response time percentile
[2020-04-06 13:01:45,711] Jonatans-Air.localdomain/ERROR/stderr:

# Fixed code
def __init__(self, *args, master_host, master_port, **kwargs):
    # Create a new RequestStats with use_response_times_cache set to False to save some memory
    # and CPU cycles. We need to create the new RequestStats before we call super() (since int's
    # used in the constructor of DistributedLocustRunner)
    self.stats = RequestStats(use_response_times_cache=False)

    super().__init__(*args, **kwargs)

    self.client_id = socket.gethostname() + "_" + uuid4().hex
    self.master_host = master_host
    self.master_port = master_port
    self.client = rpc.Client(master_host, master_port, self.client_id)
    self.greenlet.spawn(self.heartbeat)
    self.greenlet.spawn(self.worker)
    self.client.send(Message("client_ready", None, self.client_id))
    self.worker_state = STATE_INIT
    self.greenlet.spawn(self.stats_reporter)

    # register listener for when all locust users have hatched, and report it to the master node
    def on_hatch_complete(user_count):
        self.client.send(
            Message("hatch_complete", {"count": user_count}, self.client_id)
        )
        self.worker_state = STATE_RUNNING

    self.environment.events.hatch_complete.add_listener(on_hatch_complete)

    # register listener that adds the current number of spawned locusts to the report that is sent to the master node
    def on_report_to_master(client_id, data):
        data["user_count"] = self.user_count

    self.environment.events.report_to_master.add_listener(on_report_to_master)

    # register listener that sends quit message to master
    def on_quitting():
        self.client.send(Message("quit", None, self.client_id))

    self.environment.events.quitting.add_listener(on_quitting)

    # register listener thats sends locust exceptions to master
    def on_locust_error(locust_instance, exception, tb):
        formatted_tb = "".join(traceback.format_tb(tb))
        self.client.send(
            Message(
                "exception",
                {"msg": str(exception), "traceback": formatted_tb},
                self.client_id,
            )
        )

    self.environment.events.locust_error.add_listener(on_locust_error)