Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Locust / pypy fails with "AttributeError: module 'gc' has no attribute 'freeze'" error. #2818

Closed
2 tasks done
jimoleary opened this issue Jul 27, 2024 · 4 comments
Closed
2 tasks done
Labels

Comments

@jimoleary
Copy link
Contributor

Prerequisites

Description

Running a locust workload with --processes fails on pypy.

This is due to this change and it results in an AttributeError: module 'gc' has no attribute 'freeze'. The root cause is due to the fact that pypy doesn't have a freeze function.

See the following:

$ docker run --mount type=bind,source=.,target=/mnt/locust pypy:3.10 bash -c "pip3 install -q locust && locust -f /mnt/locust/examples/basic.py --processes=-1 --headless -t 5"

WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip is available: 23.0.1 -> 24.1.2
[notice] To update, run: pip install --upgrade pip
Traceback (most recent call last):
  File "/opt/pypy/bin/locust", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/opt/pypy/lib/pypy3.10/site-packages/locust/main.py", line 214, in main
    gc.freeze()  # move all objects to perm gen so ref counts dont get updated
    ^^^^^^^^^^^
AttributeError: module 'gc' has no attribute 'freeze'

The following patch fixes the issue:

From 90c0a525940dbbae8da22eded4e52ff143a68436 Mon Sep 17 00:00:00 2001
From: "jim.oleary" <[email protected]>
Date: Wed, 24 Jul 2024 18:20:31 +0100
Subject: [PATCH] fix: gc.freeze() is not currently available on pypy.

---
 locust/main.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/locust/main.py b/locust/main.py
index 16446164..c1885802 100644
--- a/locust/main.py
+++ b/locust/main.py
@@ -211,7 +211,8 @@ def main():
             sys.exit(1)
         # Optimize copy-on-write-behavior to save some memory (aprx 26MB -> 15MB rss) in child processes
         gc.collect()  # avoid freezing garbage
-        gc.freeze()  # move all objects to perm gen so ref counts dont get updated
+        if hasattr(gc, "freeze"):
+            gc.freeze()  # move all objects to perm gen so ref counts dont get updated
         for _ in range(options.processes):
             if child_pid := gevent.fork():
                 children.append(child_pid)
-- 
2.34.1

With the patch applied and installed, the workloads runs:

make dist
docker run --mount type=bind,source=.,target=/mnt/locust pypy:3.10 bash -c "pip3 install -q /mnt/locust/dist/locust-2.29.2.dev1-py3-none-any.whl && locust -f /mnt/locust/examples/basic.py --processes=-1 --headless -t 5 "     
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv

[notice] A new release of pip is available: 23.0.1 -> 24.1.2
[notice] To update, run: pip install --upgrade pip
[2024-07-27 14:19:49,636] e46c755e6b11/INFO/root: Waiting for workers to be ready, 0 of 12 connected
[2024-07-27 14:19:49,642] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_91f431ad9c8c452db2d43d8b0b942617 (index 0) reported as ready. 1 workers connected.
Type     Name                                                                          # reqs      # fails |    Avg     Min     Max    Med |   req/s  failures/s
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
--------|----------------------------------------------------------------------------|-------|-------------|-------|-------|-------|-------|--------|-----------
         Aggregated                                                                         0     0(0.00%) |      0       0       0      0 |    0.00        0.00

[2024-07-27 14:19:49,644] e46c755e6b11/INFO/locust.main: Starting Locust 2.29.2.dev1
[2024-07-27 14:19:49,775] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_1af9327b13d845dfa024cb4a1ba80152 (index 1) reported as ready. 2 workers connected.
[2024-07-27 14:19:49,777] e46c755e6b11/INFO/locust.main: Starting Locust 2.29.2.dev1
[2024-07-27 14:19:49,778] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_7f7a7ff8f7aa4f649e4870a1e8f91acd (index 2) reported as ready. 3 workers connected.
[2024-07-27 14:19:49,780] e46c755e6b11/INFO/locust.main: Starting Locust 2.29.2.dev1
[2024-07-27 14:19:49,780] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_1339140c19e94d64bab8e6f60d3379be (index 3) reported as ready. 4 workers connected.
[2024-07-27 14:19:49,782] e46c755e6b11/INFO/locust.main: Starting Locust 2.29.2.dev1
[2024-07-27 14:19:49,783] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_b55f14d4b8594903b37d2e4419ed82a1 (index 4) reported as ready. 5 workers connected.
[2024-07-27 14:19:49,785] e46c755e6b11/INFO/locust.main: Starting Locust 2.29.2.dev1
[2024-07-27 14:19:49,786] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_dbcc5bbf1913440d9305d05afad406b0 (index 5) reported as ready. 6 workers connected.
[2024-07-27 14:19:49,789] e46c755e6b11/INFO/locust.main: Starting Locust 2.29.2.dev1
[2024-07-27 14:19:49,792] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_bd31f951b61b46fc94cda4c1190aff82 (index 6) reported as ready. 7 workers connected.
[2024-07-27 14:19:49,794] e46c755e6b11/INFO/locust.runners: Worker e46c755e6b11_4e8bebbb8f6a43c9ba4d9f4205e2690d (index 7) reported as ready. 8 workers connected.

Using locust<=2.20.1 or manually launching worker processes maybe a workaround for now, but I'd like to be able to use newer versions and --processes=-1 is too convenient not to use:

docker run --mount type=bind,source=.,target=/mnt/locust pypy:3.10 bash -c "pip3 install -q 'locust<=2.20.1' && locust -f /mnt/locust/examples/basic.py --processes=-1 --headless -t 5"

Command line

docker run --mount type=bind,source=.,target=/mnt/locust pypy:3.10 bash -c "pip3 install -q locust && locust -f /mnt/locust/examples/basic.py --processes=-1 --headless -t 5"

Locustfile contents

# The locust file doesn't matter as the call fails in main.py

Python version

any pypy version

Locust version

= 2.21.0

Operating system

any

@cyberw
Copy link
Collaborator

cyberw commented Jul 27, 2024

Interesting, I didnt know anyone used pypy to run Locust :) Whats the performance like for you?

@cyberw cyberw closed this as completed Jul 27, 2024
@jimoleary
Copy link
Contributor Author

We have been evaluating testing with a mix of versions, python 3.9, python 3.12 and pypy 3.10 (v7.3.13).

For our read tests (which are lower latency):

  • 3.12 is ~50% faster than 3.9
  • pypy is ~100% faster than 3.9

There isn't a huge difference for our higher latency tests.

We haven't tried 3.13 pre release / free-threaded versions yet that sounds too scary for now!

@cyberw
Copy link
Collaborator

cyberw commented Jul 29, 2024

Cool, thanks for sharing!

We might want to look at supporting pypy properly then... we're doing a lot of work on our CI (github actions + poetry + tox) right now, but if you would come back in a couple of weeks after things settle down with a PR to add pypy to the build I'd be very happy :)

@jimoleary
Copy link
Contributor Author

TYVM, I will add it to my calendar!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants