locustio / locust

Write scalable load tests in plain Python 🚗💨
https://locust.cloud
MIT License
25.1k stars 3k forks source link

master crash with different version worker #2975

Closed uniform641 closed 1 week ago

uniform641 commented 1 week ago

Prerequisites

Description

I ran distributed locust with master node locust version 2.32.2 and some worker node locust version 2.25.0 (python3.8 default version). The master node crash with the following message

➜  load-test locust -f locust.py --master
[2024-11-09 14:41:07,519] nasa33/INFO/locust.main: Starting Locust 2.32.2
[2024-11-09 14:41:07,524] nasa33/INFO/locust.main: Starting web interface at http://0.0.0.0:8089
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
  File "/home/uniform64/.local/lib/python3.10/site-packages/locust/runners.py", line 1030, in client_listener
    if msg.data["version"][0:4] == __version__[0:4]:
TypeError: 'NoneType' object is not subscriptable
2024-11-09T06:41:13Z <Greenlet at 0x7f254a980cc0: <bound method MasterRunner.client_listener of <locust.runners.MasterRunner object at 0x7f254a963100>>> failed with TypeError

[2024-11-09 14:41:13,652] nasa33/CRITICAL/locust.runners: Unhandled exception in greenlet: <Greenlet at 0x7f254a980cc0: <bound method MasterRunner.client_listener of <locust.runners.MasterRunner object at 0x7f254a963100>>>
Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 906, in gevent._gevent_cgreenlet.Greenlet.run
  File "/home/uniform64/.local/lib/python3.10/site-packages/locust/runners.py", line 1030, in client_listener
    if msg.data["version"][0:4] == __version__[0:4]:
TypeError: 'NoneType' object is not subscriptable

when I use the following command on worker node.

~/.local/bin/locust -f - --worker --master-host 172.16.0.33 --processes -1

Command line

locust -f locust.py --master

Locustfile contents

import random
import string
from locust import HttpUser, task

def generate_random_string(length):
    return "".join(random.choices(string.ascii_lowercase+string.digits,
                                  k=length))

def generate_random_bytes(length):
    return random.randbytes(length)

class SimpleClient(HttpUser):
    @task
    def upload(self):
        # random generate a index and some data (both string)
        index = generate_random_string(random.randint(10, 20))
        data = generate_random_bytes(random.randint(100, 200))
        self.client.post("/upload", headers={"Index": index}, data=data)

Python version

3.10

Locust version

2.32.2

Operating system

ubuntu22.04

cyberw commented 1 week ago

Unfortunately we cant support significantly different worker versions (maybe within one-two minor revisions should work though). I've added a warning and stopped reading the field that might not exist, so maybe it will work for you now, but that's as far as we can go.