This function might take some time to complete if the `target_user_count` is a big number. A big number is typically > 50 000. However, this function is only called if a worker is added or removed while a test is running. Such a situation should be quite rare.
(
self, target_user_count: int
)
| 337 | return count |
| 338 | |
| 339 | def _distribute_users( |
| 340 | self, target_user_count: int |
| 341 | ) -> tuple[dict[str, dict[str, int]], Iterator[str | None], itertools.cycle, list[tuple[WorkerNode, str]]]: |
| 342 | """ |
| 343 | This function might take some time to complete if the `target_user_count` is a big number. A big number |
| 344 | is typically > 50 000. However, this function is only called if a worker is added or removed while a test |
| 345 | is running. Such a situation should be quite rare. |
| 346 | """ |
| 347 | user_gen = self._user_gen() |
| 348 | |
| 349 | worker_gen = itertools.cycle(self._worker_nodes) |
| 350 | |
| 351 | users_on_workers = { |
| 352 | worker_node.id: {user_class.__name__: 0 for user_class in self._original_user_classes} |
| 353 | for worker_node in self._worker_nodes |
| 354 | } |
| 355 | |
| 356 | active_users = [] |
| 357 | |
| 358 | user_count = 0 |
| 359 | while user_count < target_user_count: |
| 360 | user = next(user_gen) |
| 361 | if not user: |
| 362 | break |
| 363 | worker_node = next(worker_gen) |
| 364 | users_on_workers[worker_node.id][user] += 1 |
| 365 | user_count += 1 |
| 366 | active_users.append((worker_node, user)) |
| 367 | |
| 368 | return users_on_workers, user_gen, worker_gen, active_users |
| 369 | |
| 370 | def _user_gen(self) -> Iterator[str | None]: |
| 371 | weighted_users_gen = _kl_generator((u.__name__, u.weight) for u in self._user_classes if not u.fixed_count) |