Skip to content

Commit

Permalink
Support lazy initialization of reader to avoid unnecessarily doing it…
Browse files Browse the repository at this point in the history
… on workers.
  • Loading branch information
cyberw committed Dec 11, 2023
1 parent be9e188 commit 2a8b351
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
2 changes: 2 additions & 0 deletions examples/synchronizer_ex.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
else:
reader = MongoLRUReader({"env": "test", "tb": False, "lb": True}, "last_login")
synchronizer.register(reader)
# optionally replace this with lazy initalization of Reader to avoid unnecessarily doing it on workers:
# synchronizer.register(None, MongoLRUReader, {"env": "test", "tb": False, "lb": True}, "last_login")


class MyUser(HttpUser):
Expand Down
17 changes: 14 additions & 3 deletions locust_plugins/synchronizer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Dict, Iterator
from typing import Dict, Iterator, Type, Optional
import logging
from gevent.event import AsyncResult
from locust import User, events
Expand All @@ -8,19 +8,30 @@
from locust.runners import MasterRunner, WorkerRunner

test_data: Dict[int, AsyncResult] = {}
iterator: Iterator[Dict] = None
iterator: Optional[Iterator[Dict]] = None


def register(i: Iterator[dict]):
def register(i: Optional[Iterator[dict]], reader_class: Optional[Type[Iterator[Dict]]] = None, *args, **kwargs):
"""Register synchronizer methods and tie them to use the iterator that you pass.
To avoid unnecessarily instantiating the iterator on workers (where it isnt used),
you can pass an iterator class and initialization parameters instead of an object instance.
"""
global iterator
iterator = i

@events.test_start.add_listener
def test_start(environment, **_kw):
global iterator
runner = environment.runner
if not i and not isinstance(runner, WorkerRunner):
assert reader_class
logging.debug(f"about to initialize reader class {reader_class}")
iterator = reader_class(*args, **kwargs)
if runner:
# called on master
def user_request(environment: Environment, msg, **kwargs):
assert iterator # should have been instantiated by now...
data = next(iterator)
# data["_id"] = str(data["_id"]) # this is an ObjectId, msgpack doesnt know how to serialize it
environment.runner.send_message(
Expand Down

0 comments on commit 2a8b351

Please sign in to comment.