locust icon indicating copy to clipboard operation
locust copied to clipboard

Overwriting weight by config-users may lead to crash

Open evanchaoli opened this issue 1 year ago β€’ 4 comments

Prerequisites

Description

In the attached locustfile, there are no "weight" defined for both user classes, which works fine.

However, if I overwrite weights with config-users options, it will crash:

$ locust -u 2 --config-users '[{"user_class_name": "CBotApiUser", "weight": 0}]'
[2024-08-15 11:15:41,053] C02GM2X6MD6R/INFO/locust.main: Starting web interface at http://0.0.0.0:8089
init: RevisionApiUser, 1
init: CBotApiUser, 0
[2024-08-15 11:15:41,071] C02GM2X6MD6R/INFO/locust.main: Starting Locust 2.31.2
[2024-08-15 11:15:47,674] C02GM2X6MD6R/INFO/locust.runners: Ramping to 2 users at a rate of 1.00 per second
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 544, in <lambda>
    lambda: self._start(user_count, spawn_rate, wait=wait, user_classes=user_classes)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 493, in _start
    for dispatched_users in self._users_dispatcher:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 133, in __next__
    users_on_workers = next(self._dispatcher_generator)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 168, in _dispatcher
    yield self._add_users_on_workers()
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 300, in _add_users_on_workers
    for user in self._user_generator:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 388, in _user_gen
    yield next(weighted_users_gen)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 32, in _kl_generator
    heap = [(x * log2(x / (x + 1.0)), x + 1.0, x, name) for name, x in users]
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 32, in <listcomp>
    heap = [(x * log2(x / (x + 1.0)), x + 1.0, x, name) for name, x in users]
ValueError: math domain error
2024-08-15T03:15:47Z <Greenlet at 0x10ff7d900: <lambda>> failed with ValueError

[2024-08-15 11:15:47,694] C02GM2X6MD6R/CRITICAL/locust.runners: Unhandled exception in greenlet: <Greenlet at 0x10ff7d900: <lambda>>
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 544, in <lambda>
    lambda: self._start(user_count, spawn_rate, wait=wait, user_classes=user_classes)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 493, in _start
    for dispatched_users in self._users_dispatcher:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 133, in __next__
    users_on_workers = next(self._dispatcher_generator)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 168, in _dispatcher
    yield self._add_users_on_workers()
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 300, in _add_users_on_workers
    for user in self._user_generator:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 388, in _user_gen
    yield next(weighted_users_gen)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 32, in _kl_generator
    heap = [(x * log2(x / (x + 1.0)), x + 1.0, x, name) for name, x in users]
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 32, in <listcomp>
    heap = [(x * log2(x / (x + 1.0)), x + 1.0, x, name) for name, x in users]
ValueError: math domain error
KeyboardInterrupt

As you can see, I use --config-users to overwrite the second user's weight to 0, then it crashed.

Command line

$ locust -u 2 --config-users '[{"user_class_name": "CBotApiUser", "weight": 0}]'

Locustfile contents

from locust import HttpUser, task, tag, constant, events, constant_pacing


@events.init.add_listener
def on_locust_init(environment, **kwargs):
    for n, u in environment.available_user_classes.items():
        print(f'init: {n}, {u.weight}')


class RevisionApiUser(HttpUser):
    wait_time = constant_pacing(5)

    def __init__(self, environment):
        super().__init__(environment)
        self.first = True

    def on_start(self) -> None:
        print(f"revision: {self.weight}")

    @task
    def get_commit_list(self):
        if self.first:
            print(f"revision: {self.weight}")
            self.first = False


class CBotApiUser(HttpUser):
    wait_time = constant_pacing(5)

    def on_start(self) -> None:
        print(f"cbot: {self.weight}")

    def __init__(self, environment):
        super().__init__(environment)
        self.first = True

    @task
    def get_commits(self):
        if self.first:
            print(f"cbot: {self.weight}")
            self.first = False

Python version

3.9.19

Locust version

locust 2.31.2 from /Users/chaol/venv/3.9/lib/python3.9/site-packages/locust (Python 3.9.19, OpenSSL 3.3.0)

Operating system

MacOS

evanchaoli avatar Aug 15 '24 02:08 evanchaoli

Interesting. @tdadela as this is your code, do you think you could take a look?

@evanchaoli Is this issue present in 2.30.0?

cyberw avatar Aug 15 '24 09:08 cyberw

@evanchaoli Is this issue present in 2.30.0?

I am new to Locust, only tried the latest version. But I can do a quick test today.

evanchaoli avatar Aug 16 '24 01:08 evanchaoli

2.3.0 has the same problem:

$ locust -f locustfile.py  -u 2 --config-users '[{"user_class_name": "CBotApiUser", "weight": 0}]'
[2024-08-16 09:35:03,909] C02GM2X6MD6R/INFO/locust.main: Starting web interface at http://0.0.0.0:8089
init: RevisionApiUser, 1
init: CBotApiUser, 0
[2024-08-16 09:35:03,923] C02GM2X6MD6R/INFO/locust.main: Starting Locust 2.30.0
[2024-08-16 09:35:20,175] C02GM2X6MD6R/INFO/locust.runners: Ramping to 2 users at a rate of 1.00 per second
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 542, in <lambda>
    lambda: self._start(user_count, spawn_rate, wait=wait, user_classes=user_classes)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 491, in _start
    for dispatched_users in self._users_dispatcher:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 143, in __next__
    users_on_workers = next(self._dispatcher_generator)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 178, in _dispatcher
    yield self._add_users_on_workers()
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 310, in _add_users_on_workers
    for user in self._user_generator:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 409, in _user_gen
    yield next(weighted_users_gen)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 44, in _kl_generator
    heap = [(x * log2(x / (x + 1.0)), i) for i, x in enumerate(generated)]
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 44, in <listcomp>
    heap = [(x * log2(x / (x + 1.0)), i) for i, x in enumerate(generated)]
ValueError: math domain error
2024-08-16T01:35:20Z <Greenlet at 0x10dac7860: <lambda>> failed with ValueError

[2024-08-16 09:35:20,180] C02GM2X6MD6R/CRITICAL/locust.runners: Unhandled exception in greenlet: <Greenlet at 0x10dac7860: <lambda>>
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 542, in <lambda>
    lambda: self._start(user_count, spawn_rate, wait=wait, user_classes=user_classes)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/runners.py", line 491, in _start
    for dispatched_users in self._users_dispatcher:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 143, in __next__
    users_on_workers = next(self._dispatcher_generator)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 178, in _dispatcher
    yield self._add_users_on_workers()
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 310, in _add_users_on_workers
    for user in self._user_generator:
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 409, in _user_gen
    yield next(weighted_users_gen)
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 44, in _kl_generator
    heap = [(x * log2(x / (x + 1.0)), i) for i, x in enumerate(generated)]
  File "/Users/chaol/venv/3.9/lib/python3.9/site-packages/locust/dispatch.py", line 44, in <listcomp>
    heap = [(x * log2(x / (x + 1.0)), i) for i, x in enumerate(generated)]
ValueError: math domain error
KeyboardInterrupt

evanchaoli avatar Aug 16 '24 01:08 evanchaoli

tdadela said he’d get back to me, but it might be a few days. thanks for testing the old version.

cyberw avatar Aug 16 '24 09:08 cyberw